如何覆盖自定义委托 class 的 'paint' 函数来绘制 QSpinBox
How to override 'paint' function of custom delegate class to draw QSpinBox
我已将自定义委托人添加到 QTableView
。当我双击一个项目时,我会看到一个 'QSpinBox' 的编辑器小部件,我可以很好地编辑该值。一旦失去焦点,这个编辑器小部件就会消失,我明白这一点。我想要的是 QSpinBox
一直在那里。查看 Qt 示例 here 我知道我需要覆盖 QAbstractItemDelegate
class 的 paint
函数来绘制 QSpinBox
但我不知道如何那。一般来说,我想知道如何在绘图函数中绘制任何 Qt 小部件。
作为参考,我有以下测试代码:
#include <QtWidgets/QApplication>
#include <QtGui>
#include <QTableview>
#include <QLayout>
#include <QColor>
#include <QStyledItemDelegate>
#include <QSpinbox>
class SpinBoxDeligate : public QStyledItemDelegate {
public:
QWidget * createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const override {
auto w = new QSpinBox(parent);
w->setFrame(false);
w->setMinimum(0);
w->setMaximum(100);
return w;
}
void setEditorData(QWidget *editor, const QModelIndex &index) const override {
static_cast<QSpinBox*>(editor)->setValue(index.data(Qt::EditRole).toInt());
}
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override {
model->setData(index, static_cast<QSpinBox*>(editor)->value(), Qt::EditRole);
}
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
// What to replace below line with to have a QSpinBox
QStyledItemDelegate::paint(painter, option, index);
}
};
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QStandardItemModel model(3, 1);
for (int r = 0; r < 3; ++r)
{
auto text = QString("%0").arg(r);
QStandardItem* item = new QStandardItem(text);
item->setFlags(Qt::ItemIsUserCheckable
| Qt::ItemIsEnabled
| Qt::ItemIsEditable
);
item->setData(Qt::Unchecked, Qt::CheckStateRole);
item->setData(text, Qt::ToolTipRole);
item->setData(QSize(100, 30), Qt::SizeHintRole);
item->setData(QIcon(":/QtMVC/Desert.jpg"), Qt::DecorationRole);
model.setItem(r, 0, item);
}
QTableView* table = new QTableView();
table->setModel(&model);
table->setItemDelegate(new SpinBoxDeligate());
QWidget w;
QVBoxLayout* containerLayout = new QVBoxLayout();
w.setLayout(containerLayout);
containerLayout->addWidget(table);
w.show();
return app.exec();
}
您的背景问题的一个可能的解决方案是使用 paint()
并且为此您可以创建一个 QSpinBox 并使用抓取来拍摄图像,但在此之前您应该计算几何形状以便它不覆盖QCheckBox,如您所见,这是一项繁琐的工作,另一种方法是使用 QStyle,但它仍然需要更多代码。
一个简单的解决方案是使用 openPersistentEditor()
方法让编辑器保持打开状态。
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QStandardItemModel model(3, 1);
QTableView* table = new QTableView();
table->setModel(&model);
table->setItemDelegate(new SpinBoxDeligate());
for (int r = 0; r < 3; ++r)
{
auto text = QString("%0").arg(r);
QStandardItem* item = new QStandardItem(text);
item->setFlags(Qt::ItemIsUserCheckable
| Qt::ItemIsEnabled
| Qt::ItemIsEditable
);
item->setData(Qt::Unchecked, Qt::CheckStateRole);
item->setData(text, Qt::ToolTipRole);
item->setData(QSize(100, 30), Qt::SizeHintRole);
item->setData(QIcon(":/QtMVC/Desert.jpg"), Qt::DecorationRole);
model.setItem(r, 0, item);
table->openPersistentEditor(model.indexFromItem(item));
}
QWidget w;
QVBoxLayout* containerLayout = new QVBoxLayout();
w.setLayout(containerLayout);
containerLayout->addWidget(table);
w.show();
return app.exec();
}
我能想到两种可能的解决方案:
- 可以将小部件插入 table 个单元格。我知道这不是您想要做的,但它可以更好地解决您的问题。检查 setIndexWidget.
- 如果你真的要渲染QSpinBox,你应该使用QWidget的render方法。要尝试,在您的
paint
方法中创建一个 QSpinBox
并调用它的渲染方法,将 QPainter
指针传递给它。以这种方式工作后,您可以通过在 QTableView 中保存一个 'template' QSpinBox
实例并使用它在需要 [=22] 的单元格内呈现不同的 QSpinBox
值来改进您的设计=]
我已将自定义委托人添加到 QTableView
。当我双击一个项目时,我会看到一个 'QSpinBox' 的编辑器小部件,我可以很好地编辑该值。一旦失去焦点,这个编辑器小部件就会消失,我明白这一点。我想要的是 QSpinBox
一直在那里。查看 Qt 示例 here 我知道我需要覆盖 QAbstractItemDelegate
class 的 paint
函数来绘制 QSpinBox
但我不知道如何那。一般来说,我想知道如何在绘图函数中绘制任何 Qt 小部件。
作为参考,我有以下测试代码:
#include <QtWidgets/QApplication>
#include <QtGui>
#include <QTableview>
#include <QLayout>
#include <QColor>
#include <QStyledItemDelegate>
#include <QSpinbox>
class SpinBoxDeligate : public QStyledItemDelegate {
public:
QWidget * createEditor(QWidget *parent,
const QStyleOptionViewItem &option,
const QModelIndex &index) const override {
auto w = new QSpinBox(parent);
w->setFrame(false);
w->setMinimum(0);
w->setMaximum(100);
return w;
}
void setEditorData(QWidget *editor, const QModelIndex &index) const override {
static_cast<QSpinBox*>(editor)->setValue(index.data(Qt::EditRole).toInt());
}
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override {
model->setData(index, static_cast<QSpinBox*>(editor)->value(), Qt::EditRole);
}
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
// What to replace below line with to have a QSpinBox
QStyledItemDelegate::paint(painter, option, index);
}
};
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QStandardItemModel model(3, 1);
for (int r = 0; r < 3; ++r)
{
auto text = QString("%0").arg(r);
QStandardItem* item = new QStandardItem(text);
item->setFlags(Qt::ItemIsUserCheckable
| Qt::ItemIsEnabled
| Qt::ItemIsEditable
);
item->setData(Qt::Unchecked, Qt::CheckStateRole);
item->setData(text, Qt::ToolTipRole);
item->setData(QSize(100, 30), Qt::SizeHintRole);
item->setData(QIcon(":/QtMVC/Desert.jpg"), Qt::DecorationRole);
model.setItem(r, 0, item);
}
QTableView* table = new QTableView();
table->setModel(&model);
table->setItemDelegate(new SpinBoxDeligate());
QWidget w;
QVBoxLayout* containerLayout = new QVBoxLayout();
w.setLayout(containerLayout);
containerLayout->addWidget(table);
w.show();
return app.exec();
}
您的背景问题的一个可能的解决方案是使用 paint()
并且为此您可以创建一个 QSpinBox 并使用抓取来拍摄图像,但在此之前您应该计算几何形状以便它不覆盖QCheckBox,如您所见,这是一项繁琐的工作,另一种方法是使用 QStyle,但它仍然需要更多代码。
一个简单的解决方案是使用 openPersistentEditor()
方法让编辑器保持打开状态。
int main(int argc, char** argv)
{
QApplication app(argc, argv);
QStandardItemModel model(3, 1);
QTableView* table = new QTableView();
table->setModel(&model);
table->setItemDelegate(new SpinBoxDeligate());
for (int r = 0; r < 3; ++r)
{
auto text = QString("%0").arg(r);
QStandardItem* item = new QStandardItem(text);
item->setFlags(Qt::ItemIsUserCheckable
| Qt::ItemIsEnabled
| Qt::ItemIsEditable
);
item->setData(Qt::Unchecked, Qt::CheckStateRole);
item->setData(text, Qt::ToolTipRole);
item->setData(QSize(100, 30), Qt::SizeHintRole);
item->setData(QIcon(":/QtMVC/Desert.jpg"), Qt::DecorationRole);
model.setItem(r, 0, item);
table->openPersistentEditor(model.indexFromItem(item));
}
QWidget w;
QVBoxLayout* containerLayout = new QVBoxLayout();
w.setLayout(containerLayout);
containerLayout->addWidget(table);
w.show();
return app.exec();
}
我能想到两种可能的解决方案:
- 可以将小部件插入 table 个单元格。我知道这不是您想要做的,但它可以更好地解决您的问题。检查 setIndexWidget.
- 如果你真的要渲染QSpinBox,你应该使用QWidget的render方法。要尝试,在您的
paint
方法中创建一个QSpinBox
并调用它的渲染方法,将QPainter
指针传递给它。以这种方式工作后,您可以通过在 QTableView 中保存一个 'template'QSpinBox
实例并使用它在需要 [=22] 的单元格内呈现不同的QSpinBox
值来改进您的设计=]