我希望有一个包含分层项的QTreeWidget,其中一个列包含一个自定义小部件。我创建了一个自定义小部件,它在水平布局中包含一个QLabel和一个QSpinBox。
MySlider.py看起来是这样的:
from PyQt5 import QtWidgets
from PyQt5 import QtCore
from PyQt5.Qt import Qt
import sys
class MySlider(QtWidgets.QWidget):
def __init__(self, parent=None):
super(self.__class__, self).__init__(parent)
self.horizontalLayoutWidget = QtWidgets.QWidget(parent)
self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
self.label = QtWidgets.QLabel(self.horizontalLayoutWidget)
self.label.setText('Spinbox:')
self.spinBox1 = QtWidgets.QSpinBox(self.horizontalLayoutWidget)
self.horizontalLayout.addWidget(self.label)
self.horizontalLayout.addWidget(self.spinBox1)
然后,我想创建一个QTreeWidget,其中第三列填充了一个MySlider
小部件。应用程序如下所示:
import sys
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QAbstractItemView
from MySlider import MySlider
def main():
_translate = QtCore.QCoreApplication.translate
app = QtWidgets.QApplication(sys.argv)
tree = QtWidgets.QTreeWidget()
tree.setColumnCount(3)
headerItem = QtWidgets.QTreeWidgetItem()
headerItem.setText(0, _translate("MainWindow", "md-name"))
headerItem.setText(1, _translate("MainWindow", "md_value"))
headerItem.setText(2, _translate("MainWindow", "others"))
tree.setHeaderItem(headerItem)
parent = QtWidgets.QTreeWidgetItem(tree)
parent.setText(0, "Parent 1")
parent.setText(1, "")
parent.setFlags(parent.flags() | Qt.ItemIsTristate | Qt.ItemIsEditable)
for x in range(3):
child = QtWidgets.QTreeWidgetItem(parent)
child.setFlags(child.flags() | Qt.ItemIsEditable)
child.setText(0, "Child {}".format(x))
line_edit = QtWidgets.QLineEdit(tree)
rs = MySlider(tree)
tree.setItemWidget(child, 1, line_edit)
tree.setItemWidget(child, 2, rs)
tree.setEditTriggers(QAbstractItemView.AllEditTriggers)
tree.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
问题是:自定义小部件没有按需要放置在第三列中,而是显示在窗口的左上角。有人知道为什么会出错吗?
发布于 2022-05-10 11:58:12
MySlider
类的定义有几个问题。
首先,您不应该将self.__class__
与super
结合使用。在某些情况下,它可能会导致不可重构的递归,而且在任何情况下,在Python3中向super
传递参数都是完全不必要的。
其次,不需要为布局创建内部小部件,也不应该将其作为parent
参数传递给传入的对象(这实际上导致小部件在错误的位置显示)。
最后,您可能需要对布局进行一些调整,以确保自定义小部件不会占用太多空间,并且它的子部件扩展到适当的大小。
下面是这个类应该看到的样子:
class MySlider(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
layout = QtWidgets.QHBoxLayout(self)
# keep only the default margin on the left
layout.setContentsMargins(-1, 0, 0, 0)
self.label = QtWidgets.QLabel()
self.label.setText('Spinbox:')
self.spinBox1 = QtWidgets.QSpinBox()
# make sure the spin-box doesn't get too small
self.spinBox1.setMinimumWidth(80)
layout.addWidget(self.label)
layout.addWidget(self.spinBox1)
# don't allow the spin-box to exapnd too much
layout.addStretch()
如果您希望使用旋转框展开来填充整个列,则可以省略最后一行并执行以下操作:
# make sure the spin-box fills the whole column
layout.addWidget(self.spinBox1, 1)
注意,在上面的代码中,子部件没有被赋予一个显式的父部件。每当将小部件添加到布局中时,Qt将自动将它们重新父级到最终包含布局的小部件中。
https://stackoverflow.com/questions/72183924
复制相似问题