在 QTreeview 特定单元格中添加 QCombobox
Add QCombobox inside QTreeview specific cell
我试图仅在 QTreeview 的某些特定单元格中插入 QCombobox。在我阅读时,我认为我需要创建我的委托(我已经创建)。但我不明白如何将其插入到我的树视图中。
我想实现这个:
这是我的代码:
#include <QTreeView>
#include <QStandardItemModel>
#include <QStandardItem>
#include "mainwindow.h"
#include "comboboxdelegate.h"
const int ROWS = 2;
const int COLUMNS = 3;
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
treeView = new QTreeView(this);
setCentralWidget(treeView);
standardModel = new QStandardItemModel ;
standardModel->setColumnCount(2);
QStandardItem *root = new QStandardItem("ROOT");
root->setCheckable(true);
root->setCheckState(Qt::Checked);
root->setEditable(false);
standardModel->setItem(0, 0, root);
QList< QStandardItem * > listOne ;
QStandardItem *f1 = new QStandardItem( "Field_1" );
f1->setCheckable(true);
f1->setCheckState(Qt::Checked);
f1->setEditable(false);
listOne.append(f1) ;
listOne.append( new QStandardItem( "<Free text>" ) ) ;
root->appendRow(listOne);
QList< QStandardItem * > listTwo ;
QStandardItem *f2 = new QStandardItem( "Field_2" );
listTwo.append(f2) ;
listTwo.append( new QStandardItem( "<HERE COMBOBOX!>" ) ) ;
root->appendRow(listTwo);
treeView->setModel(standardModel);
treeView->expandAll();
}
我设法使用 QCombobox(使用自定义委托)创建了一个完整的列。但我不知道如何只设置特定的单元格。谁能帮帮我?
QTreeWidget 使小部件项目变得方便。
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
treeWidget = new QTreeWidget(this);
setCentralWidget(treeWidget);
treeWidget->setColumnCount(2);
auto root = new QTreeWidgetItem({"Root"});
root->setCheckState(0, Qt::Checked);
treeWidget->addTopLevelItem(root);
auto child1 = new QTreeWidgetItem({"Field 1", "<Free Text>"});
child1->setCheckState(0, Qt::Checked);
child1->setFlags(child1->flags() | Qt::ItemIsEditable);
root->addChild(child1);
auto child2 = new QTreeWidgetItem({"Field 2"});
child2->setFlags(child2->flags() | Qt::ItemIsEditable);
root->addChild(child2);
auto comboBox = new QComboBox();
comboBox->addItems({"Red", "Blue", "Yellow"});
treeWidget->setItemWidget(child2, 1, comboBox);
connect(treeWidget, &QTreeWidget::itemDoubleClicked, treeWidget, &QTreeWidget::editItem);
treeWidget->expandAll();
}
需要注意一些差异。
您的 class 声明中需要 QTreeWidget* treeWidget;
。并包含 QTreeWidget header.
默认情况下,TreeWidgetItems 不可检查(无复选框),但使用 Qt::Checked
或 Qt::Unchecked
调用 QTreeWidgetItem::setCheckState
将使其可检查。
项目默认不可编辑。可以通过调用 treeWidgetItem->setFlags(treeWidgetItem->flags() | Qt::ItemIsEditable)
使整个 行 成为可编辑的。要过滤 rows/columns 可以编辑的内容,您可以定义自己的 itemDoubleClicked 插槽并使用 if-statement (example).
您需要在模型项中存储组合框项,例如使用 Qt::UserRole
QStringList options = {"one", "two", "three"};
QStandardItem* item = new QStandardItem(options[0]);
item->setData(QVariant(options),Qt::UserRole);
listTwo.append(item);
然后你需要指派代表查看。如果 index.data(Qt::UserRole).isNull()
.
,您可以为整个 table 和 return 默认委托分配它
Delegate* delegate = new Delegate(treeView);
treeView->setItemDelegate(delegate);
将编辑触发器设置为全部可能是个好主意,这样下拉菜单不仅在双击时出现,而且在单击时也会出现
treeView->setEditTriggers(QAbstractItemView::AllEditTriggers);
代表必须实施 createEditor
、setEditorData
和 setModelData
QWidget *Delegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (index.data(Qt::UserRole).isNull()) {
return QStyledItemDelegate::createEditor(parent, option, index);
}
return new QComboBox(parent);
}
void Delegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
QComboBox* comboBox = qobject_cast<QComboBox*>(editor);
if (!comboBox) {
return QStyledItemDelegate::setEditorData(editor, index);
}
QStringList options = index.data(Qt::UserRole).toStringList();
comboBox->addItems(options);
QString value = index.data().toString();
int current = options.indexOf(value);
if (current > -1) {
comboBox->setCurrentIndex(current);
}
comboBox->showPopup();
}
void Delegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QComboBox* comboBox = qobject_cast<QComboBox*>(editor);
if (!comboBox) {
return QStyledItemDelegate::setModelData(editor, model, index);
}
model->setData(index, comboBox->currentText());
}
默认情况下,委托不会更改项目的显示方式,并且仅在触发编辑时才显示编辑器:不显示组合框。但是您可以使用自定义 paintEvent
.
覆盖它
void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (index.data(Qt::UserRole).isNull()) {
return QStyledItemDelegate::paint(painter, option, index);
}
QStyle* style = qApp->style();
QStyleOptionComboBox opt;
opt.rect = option.rect;
opt.currentText = index.data().toString();
opt.palette = option.palette;
opt.state = option.state;
opt.subControls = QStyle::SC_All;
opt.activeSubControls = QStyle::SC_All;
opt.editable = false;
opt.frame = true;
style->drawComplexControl(QStyle::CC_ComboBox, &opt, painter, 0);
style->drawControl(QStyle::CE_ComboBoxLabel, &opt, painter, 0);
}
完整来源:combobox-delegate
我试图仅在 QTreeview 的某些特定单元格中插入 QCombobox。在我阅读时,我认为我需要创建我的委托(我已经创建)。但我不明白如何将其插入到我的树视图中。
我想实现这个:
这是我的代码:
#include <QTreeView>
#include <QStandardItemModel>
#include <QStandardItem>
#include "mainwindow.h"
#include "comboboxdelegate.h"
const int ROWS = 2;
const int COLUMNS = 3;
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
treeView = new QTreeView(this);
setCentralWidget(treeView);
standardModel = new QStandardItemModel ;
standardModel->setColumnCount(2);
QStandardItem *root = new QStandardItem("ROOT");
root->setCheckable(true);
root->setCheckState(Qt::Checked);
root->setEditable(false);
standardModel->setItem(0, 0, root);
QList< QStandardItem * > listOne ;
QStandardItem *f1 = new QStandardItem( "Field_1" );
f1->setCheckable(true);
f1->setCheckState(Qt::Checked);
f1->setEditable(false);
listOne.append(f1) ;
listOne.append( new QStandardItem( "<Free text>" ) ) ;
root->appendRow(listOne);
QList< QStandardItem * > listTwo ;
QStandardItem *f2 = new QStandardItem( "Field_2" );
listTwo.append(f2) ;
listTwo.append( new QStandardItem( "<HERE COMBOBOX!>" ) ) ;
root->appendRow(listTwo);
treeView->setModel(standardModel);
treeView->expandAll();
}
我设法使用 QCombobox(使用自定义委托)创建了一个完整的列。但我不知道如何只设置特定的单元格。谁能帮帮我?
QTreeWidget 使小部件项目变得方便。
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
treeWidget = new QTreeWidget(this);
setCentralWidget(treeWidget);
treeWidget->setColumnCount(2);
auto root = new QTreeWidgetItem({"Root"});
root->setCheckState(0, Qt::Checked);
treeWidget->addTopLevelItem(root);
auto child1 = new QTreeWidgetItem({"Field 1", "<Free Text>"});
child1->setCheckState(0, Qt::Checked);
child1->setFlags(child1->flags() | Qt::ItemIsEditable);
root->addChild(child1);
auto child2 = new QTreeWidgetItem({"Field 2"});
child2->setFlags(child2->flags() | Qt::ItemIsEditable);
root->addChild(child2);
auto comboBox = new QComboBox();
comboBox->addItems({"Red", "Blue", "Yellow"});
treeWidget->setItemWidget(child2, 1, comboBox);
connect(treeWidget, &QTreeWidget::itemDoubleClicked, treeWidget, &QTreeWidget::editItem);
treeWidget->expandAll();
}
需要注意一些差异。
您的 class 声明中需要
QTreeWidget* treeWidget;
。并包含 QTreeWidget header.默认情况下,TreeWidgetItems 不可检查(无复选框),但使用
Qt::Checked
或Qt::Unchecked
调用QTreeWidgetItem::setCheckState
将使其可检查。项目默认不可编辑。可以通过调用
treeWidgetItem->setFlags(treeWidgetItem->flags() | Qt::ItemIsEditable)
使整个 行 成为可编辑的。要过滤 rows/columns 可以编辑的内容,您可以定义自己的 itemDoubleClicked 插槽并使用 if-statement (example).
您需要在模型项中存储组合框项,例如使用 Qt::UserRole
QStringList options = {"one", "two", "three"};
QStandardItem* item = new QStandardItem(options[0]);
item->setData(QVariant(options),Qt::UserRole);
listTwo.append(item);
然后你需要指派代表查看。如果 index.data(Qt::UserRole).isNull()
.
Delegate* delegate = new Delegate(treeView);
treeView->setItemDelegate(delegate);
将编辑触发器设置为全部可能是个好主意,这样下拉菜单不仅在双击时出现,而且在单击时也会出现
treeView->setEditTriggers(QAbstractItemView::AllEditTriggers);
代表必须实施 createEditor
、setEditorData
和 setModelData
QWidget *Delegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (index.data(Qt::UserRole).isNull()) {
return QStyledItemDelegate::createEditor(parent, option, index);
}
return new QComboBox(parent);
}
void Delegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
QComboBox* comboBox = qobject_cast<QComboBox*>(editor);
if (!comboBox) {
return QStyledItemDelegate::setEditorData(editor, index);
}
QStringList options = index.data(Qt::UserRole).toStringList();
comboBox->addItems(options);
QString value = index.data().toString();
int current = options.indexOf(value);
if (current > -1) {
comboBox->setCurrentIndex(current);
}
comboBox->showPopup();
}
void Delegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QComboBox* comboBox = qobject_cast<QComboBox*>(editor);
if (!comboBox) {
return QStyledItemDelegate::setModelData(editor, model, index);
}
model->setData(index, comboBox->currentText());
}
默认情况下,委托不会更改项目的显示方式,并且仅在触发编辑时才显示编辑器:不显示组合框。但是您可以使用自定义 paintEvent
.
void Delegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if (index.data(Qt::UserRole).isNull()) {
return QStyledItemDelegate::paint(painter, option, index);
}
QStyle* style = qApp->style();
QStyleOptionComboBox opt;
opt.rect = option.rect;
opt.currentText = index.data().toString();
opt.palette = option.palette;
opt.state = option.state;
opt.subControls = QStyle::SC_All;
opt.activeSubControls = QStyle::SC_All;
opt.editable = false;
opt.frame = true;
style->drawComplexControl(QStyle::CC_ComboBox, &opt, painter, 0);
style->drawControl(QStyle::CE_ComboBoxLabel, &opt, painter, 0);
}
完整来源:combobox-delegate