如何在 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委托