Qt Mithilfe von Benutzerdefinierten QItemDelegate für QTableView
Ich folgte der Spin-Box-Delegieren-tutorial, die Qt bietet, zu versuchen, meine eigenen QItemDelegate
. Es würde verwendet werden, um anzugeben, eine QComboBox
zur Darstellung von Daten in einem QTableView
Zelle, aber es funktioniert nicht.
Mein größtes problem ist, dass ich nicht weiß, Wann meine QItemDelegate
wird verwertet.
-
wenn
itemModel->setData()
verwendet wird, oder wennitemModel->setItem()
. Ich würde vermutensetItem()
weil ich reimplementiert eineQItemDelegate
(Betonung auf "Element"), aber das tutorial verwendetsetData()
und es funktioniert gut. -
Ich weiß, dass, wenn die angegebene
QItemDelegate
funktioniert nicht, es nutzt die Standard ein, aber wie kann ich jetzt die, die ich angegeben habe nicht funktioniert? -
Wann sollte ich vermute für
QTableView
um meine delegieren. Ich möchte, um anzugeben, welche Delegierten für jede Zelle. Ist das möglich oder muss dasQTableView
verwenden Sie nur einen Abgeordneten im ganzen? -
Wie würde ich die Elemente angegeben, die zum Auffüllen der
QComboBox
einmal wird angezeigt, indem dieQTableView
?
Ich umgesetzt QItemDelegate
hier:
- der Teil, wo ich versuche, um die Zelle angenommen, die Verwendung der
QComboBox
ist unter dem Kommentar "Aktiviert" in mainwindow.cpp weiter unten in diesem post.
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 : dies ist, wo ich das initialisieren der 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 : dies ist, wo ich ein update 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);
}
Bearbeiten 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);
}
}
mainwindow.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);
}
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ersten haben, sollten Sie eine Beschreibung Ihres Modells Spalten:
Ihre Delegierten sollten nur für die Letzte Spalte.
Hier ist ein Beispiel, wie Sie können füllen Sie Ihr Modell:
Wie gesagt, der bevollmächtigte sollten nur für die Letzte Spalte. Also alle Methoden, die Sie haben reimplementiert sollte eine Spalte zu überprüfen, wie diese:
Sollten Sie diese überprüfen, um zu den anderen Methoden: wenn die aktuelle Spalte ist nicht der status-Spalte der base-Klasse (
QItemDelegate
) - Implementierung verwendet werden soll.Dann stellen Sie Ihre Delegierten zu Ihrer Ansicht:
Wenn du alles richtig machst, wird eine combo-Box erscheint in der letzten Spalte, wenn Sie versuchen, Bearbeiten Sie die Werte.
So habe ich herausgefunden, dass ich nicht überschreiben der korrekten Funktion des Prototypen..! Ich vergaß, dass Sie
hatten const in der Prototyp-was bedeutet, dass ich nicht überschreiben alle Funktionen, so war es mit den Standardeinstellungen. Hier sind die richtigen virtuellen Funktionen, die neu implementiert: http://qt-project.org/doc/qt-5.0/qtwidgets/qitemdelegate.html
override
- Schlüsselwort von C++11. en.cppreference.com/w/cpp/language/overrideSogar mehr einfach; ich fand QTableView::setItemDelegateForColumn() arbeiten, eignen sich vorzüglich für eine Spalte. Zum Beispiel, in Ihrem MainWindow, könnten Sie ein Mitglied:
Dann im Tor, oder init(), die Sie haben könnten
Wenn Sie wollte, um das geschehen für eine einzelne Zelle, die, wenn Sie brauchen, um zu testen auf dem index.Spalte() und index.Zeile().
Sie wissen, dass Sie nicht haben, um eine QTableView, dies zu tun entweder. E. g., sehen ?:
Qt - Zentrierung eine checkbox in einer QTable
Die OP doesn ' T geben Sie die Deklaration für eine Tabelle-widget oder Ansicht; aber es hat die QTableView tag. Es sollte funktionieren gleich gut für Sie entweder.
In diesem Fall, Sie können tun
ui->tableWidget->setItemDelegateForColumn(2, dgtComboDelegate);
und nie haben, um Ihr eigenes Modell. Verwenden Sie einfach setData() auf die Elemente, die Sie erstellen (oder auch später, für diese Angelegenheit) zu initialisieren Ihrer Werte.