Qt使用自定义QItemDelegate用于QTableView [英] Qt Using Custom QItemDelegate for QTableView
问题描述
我遵循了Qt提供的Spin Box Delegate教程,尝试实现自己的 QItemDelegate
。它将用于指定 QComboBox
来表示 QTableView
单元格中的数据,但是它不起作用。
I followed the Spin Box Delegate tutorial, which Qt provides, to try to implement my own QItemDelegate
. It would be used to specify a QComboBox
to represent data in a QTableView
cell but it is not working.
我最大的问题是我不知道何时我的 QItemDelegate
将被利用。
My biggest problem is that I don't know when my QItemDelegate
is going to be utilized.
-
当<$ c使用$ c> itemModel-> setData()或使用
itemModel-> setItem()
时。我会怀疑setItem()
,因为我重新实现了QItemDelegate
(强调 Item),但是本教程使用了setData()
,它可以正常工作。
when
itemModel->setData()
is used or whenitemModel->setItem()
. I would suspectsetItem()
because I reimplemented aQItemDelegate
(emphasis on the "Item") but the tutorial usessetData()
and it works fine.
我知道如果指定了 QItemDelegate
不起作用,它使用默认值,但是我现在指定的那个不起作用怎么办?
I know that if the specified QItemDelegate
does not work it uses the default one but how do I now that the one I specified did not work?
何时应该使用我怀疑 QTableView
使用我的委托。我想指定用于每个单元的代表。这可能吗?还是 QTableView
整个过程中只使用一个委托?
when should I suspect for QTableView
to use my delegate. I would like to specify which delegates to use for each cell. Is this possible or does the QTableView
only use one delegate throughout?
我将如何指定项目?在 QTableView
显示后,如何填充 QComboBox
?
How would I specify the items to populate the QComboBox
once it gets displayed by the QTableView
?
我在此处实现了 QItemDelegate
:
- 我尝试添加要使用
QComboBox
的单元格的部分在mainwindow.cpp中的注释 Enabled下。
- the part where I try to add the cell which is suppose to use the
QComboBox
is under the comment "Enabled" in mainwindow.cpp further down this post.
qcomboboxitemdelegate.h
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
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
mainwindow.cpp : this is where I initialize the 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的地方
mainwindow.cpp : this is where I 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);
}
编辑1
qcomboboxdelegate.cpp
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
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);
}
推荐答案
首先,您应该有一个模型列的说明:
First, you should have a description of your model columns:
enum Columns
{
COL_NAME,
COL_TIME,
COL_STATUS
}
您的代表只能在最后一列工作。
Your delegate should only work for the last column.
以下是如何填充模型的示例:
Here is an example of how you can populate your model:
for (int i = 0; i < 5; ++i)
{
QStandardItem *itemName = new QStandardItem(QString("name %1").arg(i));
QStandardItem *itemTime = new QStandardItem(QString("time %1").arg(i));
QString status;
if (i % 2 == 0)
{
status = "Enabled";
}
else
{
status = "Disabled";
}
QStandardItem *itemStatus = new QStandardItem(status);
QList<QStandardItem*> row;
row << itemName << itemTime << itemStatus;
model->appendRow(row);
}
正如我所说,您的代表只应为最后一栏工作。因此,您重新实现的所有方法都应进行如下列检查:
As I said, your delegate should only work for the last column. So all methods you have reimplemented should have a column check like this:
QWidget* QComboBoxItemDelegate::createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index)
{
if (index.column() == COL_STATUS)
{
QStringList values;
values << "Enabled" << "Disabled";
QComboBox* comboBox = new QComboBox(parent);
comboBox->addItems(values);
return comboBox;
}
else
{
return QItemDelegate::createEditor(parent, option, index);
}
}
您应该将此检查添加到其他方法中:当前列不是状态列,应使用基类( QItemDelegate
)实现。
You should add this check to the other methods: if the current column is not the status column, the base class (QItemDelegate
) implementation should be used.
然后您将您的代表设置为您的视图:
Then you set your delegate to your view:
ui->tableView->setItemDelegate(new ComboBoxDelegate);
如果您做的一切正确,那么如果您尝试编辑其组合框,组合框将出现在最后一列中值。
If you do everything right, a combo Box will appear in the last column if you try to edit its values.
这篇关于Qt使用自定义QItemDelegate用于QTableView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!