PyQT:树视图列中的QPushButton委托
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PyQT:树视图列中的QPushButton委托相关的知识,希望对你有一定的参考价值。
我知道在C++中有一个同样目标的问题,但我没有成功在树视图中实现按钮委托。所以我在这里提出一个新问题,即使我知道之前有一个同样目标的问题。我只想要进一步解释。
因此,几天后,我设法在树视图中实现一个多节点树模型,这要归功于video tutorial和代码源here和here但现在我想在最后一级的每个子节点旁边添加一个委托按钮。树模型。在查阅关于模型/视图编程的Qt文档后,搜索around并阅读Mark Summerfield Rapid GUI Programming with Python and QT一书中的第14,15和16章,并使用createEditor()
,setEditordata()
和setModelData()
搜索如何添加Qwidget委托我仍然很难显示“The”按钮...
所以我开始创建按钮类委托:
class ButtonDelegate(QtGui.QItemDelegate):
"""
A delegate that places a fully functioning Button in every
cell of the column to which it's applied
"""
def __init__(self, parent):
QtGui.QItemDelegate.__init__(self, parent)
def createEditor(self, parent, option, index):
button = QtGui.QPushButton("Simple button", parent)
self.connect(button, QtCore.SIGNAL("clicked()"), self, QtCore.SLOT("handle_button()"))
return button
@QtCore.pyqtSlot()
def handle_button(self):
sender = self.sender()
print("Button pushed: {}".format(self.sender()))
在这里你看到我没有实现setEditordata()
和setModelData()
,因为我已经将按钮连接到def handle_button(self)
并且我只是想打印孩子的名字暂时(只是为了简化)。
我使用setItemDelegateForColumn(int, AbstractItemDelegate)
来设置委托我也知道,为了显示按钮,你必须将这个方法指定给treeview QAbstractItemView.openPersistentEditor(QModelIndex)
。但我不知道该把什么作为论点......
我很抱歉“重新发布”一个问题,但此刻我已经走到了尽头...我不知道从哪里开始。
我用Python编写代码,但如果你用C ++回答我会弄清楚,不要担心。
再次感谢您的帮助。
使用setIndexWidget
可能是一个解决方案,但由于你必须为每个最后一个子项设置它,这可能需要太多的编码,并且可能容易出现错误和头痛...我建议直接在委托中使用按钮QStyle的方法。
这是一个简单的实现:
class ButtonDelegate(QtGui.QStyledItemDelegate):
def paint(self, painter, option, index):
QtGui.QStyledItemDelegate.paint(self, painter, option, index)
if index.model().hasChildren(index):
return
rect = option.rect
btn = QtGui.QStyleOptionButton()
btn.rect = QtCore.QRect(rect.left() + rect.width() - 30, rect.top(), 30, rect.height())
btn.text = '...'
btn.state = QtGui.QStyle.State_Enabled|(QtGui.QStyle.State_MouseOver if option.state & QtGui.QStyle.State_MouseOver else QtGui.QStyle.State_None)
QtGui.QApplication.style().drawControl(QtGui.QStyle.CE_PushButton, btn, painter)
这是它的样子......
显然你必须实现自己的信号,但是,由于editorEvent
自动处理鼠标事件,这将是一个简单的任务,检测event.pos()
是否在“虚拟”按钮QRect
。
在上面的示例中,我添加了一个简单的悬停检测,只要鼠标指针位于项目上方,就会在按钮上设置“鼠标悬停外观”,但是只有当指针实际位于按钮上时,您可能更喜欢使用悬停样式。
由于paint
无法检测到鼠标位置,因此有两种可能的解决方案。您可以使用专门用于视图的委托,并在初始化委托时将视图的实例添加为参数(然后您可以轻松地将mapFromGlobal
与QtGui.QCursor.pos()
一起使用并根据option.rect
检索其位置 - 只需记住您必须将其映射到viewport
,不是观点);或者你创建一个特定的UserRole,你在其中用event.pos()
方法将editorEvent
写入项目,然后从paint
方法中读取它。要实现这一点,必须在视图上启用mouseTracking
。
进一步评论
可以想象,当树级太深而视图的宽度不足以显示项目本身时,项目的外观会出现问题。您可以查看option.rect
的可用尺寸,如果您不想隐藏该项目,或者如果没有足够的可用空间则不显示该按钮。
另一个缺点是该项目的文字可能被按钮涂抹,有些样式可能会导致一些丑陋的外观。如果项目文本的fontMetrics不允许完全显示,您可以决定使用fontMetrics的elideText()
方法(通过减去按钮的宽度)来消除文本,或者简单地“屏蔽”按钮的右侧。
但请注意:如果您有多个列,则按钮的“隐藏”右侧部分将不会被隐藏,但它将成为下一列的一部分。
以上是关于PyQT:树视图列中的QPushButton委托的主要内容,如果未能解决你的问题,请参考以下文章
突出显示qpushbutton pyqt中的单个字符[重复]
PyQt4:使用 QPushButton 小部件从 QList 小部件中删除项目
PyQt / Qt,带有自定义委托的表格视图以使用省略号来处理文本溢出单元格