如何在 QTableView 中绘制自定义控件?

Posted

技术标签:

【中文标题】如何在 QTableView 中绘制自定义控件?【英文标题】:How to draw a custom control in QTableView? 【发布时间】:2012-10-09 09:44:42 【问题描述】:

我必须在 QTableView 中绘制一个自定义控件。这个控件必须看起来像 FileChooser。

FileChooser http://www.vision.ee.ethz.ch/computing/sepp-irix/qt-3.0-mo/filechooser.png

QStyleOptionButton button_option;
button_option.state |= QStyle::State_Enabled | QStyle::State_Off;
button_option.rect = PushButtonRect(option); //calculate button rect
button_option.text = "...";
QApplication::style()->drawControl(
    QStyle::CE_PushButton,
    &button_option,
    painter);

上面的代码绘制了 QStyle::CE_PushButton - 看起来像 QButton,但在 Qt 库中没有 QStyle::CE_LineEdit。如何绘制 QLineEdit?

【问题讨论】:

【参考方案1】:

为了在表格视图中绘制自定义小部件,您需要创建一个自定义QItemDelegate 子类并至少覆盖createEditor 方法,您可以在其中创建双击时显示的任何类型的小部件表格单元格。可以将此项目委托分配给表格视图中的相应列。

然后您需要创建一个单独的类,例如CustomFileChooser,继承自 QWidget,由 Line Edit 和 Button 组成。

然后您的 createEditor 方法将返回这样一个对象。

您可能还必须覆盖 setEditorData(它将当前模型值分配给创建的编辑器小部件)和 setModelData(在提交更改时调用)。

这样,行编辑和按钮只有在双击表格单元格后才可见。如果您希望它始终可见,则还必须覆盖 drawDisplay()。

【讨论】:

控件应该始终可见。需要解决上述问题(将 QLineEdit 绘制为 QStyle::ControlElement)以覆盖 drawDisplay(和 drawFocus),不是吗?但我选择了另一种方式。我的委托继承自 QStyledItemDelegate,我尝试覆盖paint 和 editorEvent 方法。 Example for Checkbox control.【参考方案2】:

我自己找到了答案。您可以使用以下方式永久显示自定义编辑器(普通小部件):

void QAbstractItemView::openPersistentEditor ( const QModelIndex & index )

【讨论】:

您能否将此问题的主题更改为“如何在 QTableView / QAbstractItemView 中永久显示自定义小部件/委托?”。强调“永久”。我认为这会在这个问题上帮助很多人。【参考方案3】:

首先您需要了解按钮是控制元素,因此您可以在 CE 下找到它,但当您需要 lineEdit 时,它不是控制元素。 为了画lineEdit,我将引用qt文档,

“QStyleOptionFrameV2继承了QStyleOptionFrame,用于绘制Qt内置的几个小部件,包括QFrame、QGroupBox、QLineEdit和QMenu。”

是的,只有一个可能有效的示例代码才能帮助您清楚地理解它! 代码应该看起来像这样

QStyleOptionFrameV2 *panelFrame = new QStyleOptionFrameV2;
QLineEdit *search = new QLineEdit;
panelFrame->initFrom(search);
panelFrame->rect = QRect(x,y,w,h);//Indeed the location and the size
panelFrame->lineWidth = QApplication::style->pixelMetric(QStyle::PM_DefaultFrameWidth, panelFrame, search);
panelFrame->state |= QStyle::State_Sunken;
QApplication::style()->drawPrimitive(QStyle::PE_PanelLineEdit, panelFrame, painter);

【讨论】:

所以它不是自定义控件...因此不使用drawControl绘制...这个问题的主题应该更改为drawPrimitive ....

以上是关于如何在 QTableView 中绘制自定义控件?的主要内容,如果未能解决你的问题,请参考以下文章

QT中级QTableView自定义委托实现QSpinBoxQDoubleSpinBox委托

强制在自定义 WPF 控件中重新绘制自定义绘制的 UIElement

如何在双向绑定的Image控件上绘制自定义标记(wpf)

如何保持自定义绘制的复选框控件的透明度

Android_(控件)使用自定义控件在屏幕中绘制一条虚线

自定义控件知识储备-View的绘制流程