17

Qt が提供する Spin Box Delegate チュートリアルに従って、独自のQItemDelegate. を指定してセル内QComboBoxのデータを表すために使用されますが、機能していません。QTableView

ここに画像の説明を入力

私の最大の問題は、いつ使用されるかわからないことQItemDelegateです。

  • whenitemModel->setData()が使用される場合または when が使用される場合itemModel->setItem()。(「アイテム」を強調して)setItem()を再実装したためと思われますが、チュートリアルでは使用しており、正常に動作します。QItemDelegatesetData()

  • 指定したものが機能しない場合はデフォルトのものを使用することはわかっていますが、指定QItemDelegateしたものが機能しなかった場合はどうすればよいですか?

  • QTableViewデリゲートをいつ使用するかを疑う必要があります。各セルに使用するデリゲートを指定したいと思います。これは可能ですか、QTableViewそれとも全体で 1 つのデリゲートのみを使用しますか?

  • QComboBoxによって表示されたら、アイテムを入力するように指定するにはどうすればよいQTableViewですか?

ここで実装QItemDelegateしました:

  • 使用すると思われるセルを追加しようとする部分は、QComboBoxこの投稿のさらに下の mainwindow.cpp のコメント「有効」の下にあります。

qcomboboxitemdelegate.h

#ifndef QCOMBOBOXITEMDELEGATE_H
#define QCOMBOBOXITEMDELEGATE_H

#include <QItemDelegate>
#include <QComboBox>

class QComboBoxItemDelegate : public QItemDelegate
{
    Q_OBJECT

public: 

    explicit QComboBoxItemDelegate(QObject *parent = 0);

    QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index);
    void setEditorData(QWidget *editor, const QModelIndex &index);
    void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index);
    void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,     const QModelIndex &index);

signals:

private:

};

#endif // QCOMBOBOXITEMDELEGATE_H

qcomboboxitemdelegate.cpp

#include "qcomboboxitemdelegate.h"
#include <QDebug>

QComboBoxItemDelegate::QComboBoxItemDelegate(QObject *parent)
: QItemDelegate(parent)
{

}

QWidget* QComboBoxItemDelegate::createEditor(QWidget *parent, const   QStyleOptionViewItem &option, const QModelIndex &index) {
    // create widget for use
    QComboBox* comboBox = new QComboBox(parent);
    return comboBox;
}

void QComboBoxItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) {
    // update model widget
    QString value = index.model()->data(index, Qt::EditRole).toString();
    qDebug() << "Value:" << value;
    QComboBox* comboBox = static_cast<QComboBox*>(editor);
    comboBox->setCurrentIndex(comboBox->findText(value));
}

void QComboBoxItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,   const QModelIndex &index) {
    // store edited model data to model
    QComboBox* comboBox = static_cast<QComboBox*>(editor);
    QString value = comboBox->currentText();
    model->setData(index, value, Qt::EditRole);
}

void QComboBoxItemDelegate::updateEditorGeometry(QWidget *editor, const     QStyleOptionViewItem &option, const QModelIndex &index) {
    editor->setGeometry(option.rect);
}

mainwindow.cpp : ここで初期化しますQStandardItemModel

void MainWindow::init() {
    itemModel = new QStandardItemModel(this);
}

void MainWindow::setupUi() {
    this->setWindowTitle("QAlarmClock");        
    QStringList labelList;
    labelList << "Alarm Name" << "Time" << "Enabled";
    itemModel->setHorizontalHeaderLabels(labelList);    
    ui->tableView->setModel(itemModel);
    ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    ui->tableView->setItemDelegate(comboBoxItemDelegate);
}

void MainWindow::on_actionNew_triggered() {
    alarmDialog = new AlarmDialog(this);
    connect(alarmDialog, SIGNAL(on_close()), this, SLOT(on_alarmDialog_close()));
    alarmDialog->exec();
}

mainwindow.cpp : ここで更新しますQStandardItemModel

void MainWindow::on_alarmDialog_close() {
    QString alarmName = alarmDialog->getAlarmName();
    QDateTime alarmDateTime = alarmDialog->getDateTime();

    itemModel->insertRow(itemModel->rowCount());
    int rowCount = itemModel->rowCount();

    // Alarm Name
    QStandardItem* alarmItem = new QStandardItem(QIcon("res/alarmclock.ico"),  alarmName);
    itemModel->setItem(rowCount - 1 , 0, alarmItem);

    // Date Time
    QStandardItem* dateTimeItem = new QStandardItem();
    dateTimeItem->setText(alarmDateTime.toString());
    dateTimeItem->setEditable(false);
    itemModel->setItem(rowCount - 1, 1, dateTimeItem);

    // Enabled
    QStandardItem* enabledItem = new QStandardItem();
    QList<QStandardItem*> optionList;
    optionList << new QStandardItem("Enabled") << new QStandardItem("Disabled");
    enabledItem->appendRows(optionList);
    itemModel->setItem(rowCount - 1, 2, enabledItem);
}

編集 1

qcomboboxdelegate.cpp

QWidget* QComboBoxItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) {
    // create widget for use
    qDebug() << "Column: " << index.column();
    if (index.column() == 2) {
        QComboBox* comboBox = new QComboBox(parent);
        QStringList values;
        values << "Enabled" << "Disabled";
        comboBox->addItems(values);
        return comboBox;
    } else {
        return QItemDelegate::createEditor(parent, option, index);
    }
}

メインウィンドウ.cpp

void MainWindow::on_alarmDialog_close() {
    QList<QStandardItem*> row;

    QString alarmName = alarmDialog->getAlarmName();
    QDateTime alarmDateTime = alarmDialog->getDateTime();
    QString status = "Enabled";

    // Alarm Name
    QStandardItem* alarmItem = new QStandardItem(QIcon("res/alarmclock.ico"), alarmName);
    row << alarmItem;

    // Date Time
    QStandardItem* dateTimeItem = new QStandardItem();
    dateTimeItem->setText(alarmDateTime.toString());
    dateTimeItem->setEditable(false);
    row << dateTimeItem;

    // Enabled
    QStandardItem* statusItem = new QStandardItem(status);
    row << statusItem;

    itemModel->appendRow(row);
}
4

3 に答える 3

3

さらに簡単に。QTableView::setItemDelegateForColumn() が列に対して見事に機能することがわかりました。たとえば、MainWindow でメンバーを作成できます。

QComboBoxItemDelegate dgtComboDelegate;

次に、ctor または init() で、

ui->tableView->setItemDelegateForColumn(2, dgtComboDelegate);

単一のセルでそれを実現したい場合は、index.column() と index.row() をテストする必要があります。

これを行うために QTableView を作成する必要もありません。たとえば、?: を参照してください。

Qt - QTable のチェックボックスを中央に配置する

OP は、テーブル ウィジェットまたはビューの宣言を行いません。しかし、QTableView タグがあります。どちらでも同じように機能するはずです。

前者の場合、ui->tableWidget->setItemDelegateForColumn(2, dgtComboDelegate);独自のモデルを作成する必要はありません。作成したアイテムに対して setData() を使用するだけで (さらに言えば後で)、それらの値を初期化できます。

于 2018-11-07T19:28:24.847 に答える
2

そのため、正しい関数プロトタイプをオーバーライドしていないことがわかりました..! プロトタイプに const があることを忘れていました。つまり、関数をオーバーライドしていないため、デフォルトの関数を使用していました。再実装する必要がある正しい仮想関数は次のとおりです: http://qt-project.org/doc/qt-5.0/qtwidgets/qitemdelegate.html

于 2013-05-21T14:52:00.833 に答える