python - 调用类在窗口内构建QTreeWidget : argument 1 has unexpected type 'Ui_MainWindow'

标签 python pyqt4 qtreewidget qtreewidgetitem qtxml

我正在使用从 ekhumoro 获得的代码从我创建的 GUI 的 xml 文件动态创建树,但是当尝试调用从 pyuic4 生成的 _ui.py 文件内的类时,我得到的是返回的 Ui_MainWindow 类,而不是预期的参数。

XmlHandler,它创建树项(根据我的理解):

from PyQt4 import QtCore, QtGui, QtXml
from PyQt4.QtXml import *


class XmlHandler(QXmlDefaultHandler):
    def __init__(self, root):
        QtXml.QXmlDefaultHandler.__init__(self)
        self._root = root
        self._item = None
        self._text = ''
        self._error = ''

    def startElement(self, namespace, name, qname, attributes):
        if qname == 'Machine' or qname == 'Feature':
            if self._item is not None:
                self._item = QtGui.QTreeWidgetItem(self._item)
            else:
                self._item = QtGui.QTreeWidgetItem(self._root)
            self._item.setData(0, QtCore.Qt.UserRole, qname)
            self._item.setText(0, 'Unknown Machine')
            if qname == 'Machine':
                self._item.setExpanded(False)
                self._item.setCheckState(0, QtCore.Qt.Unchecked)
                self._item.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsDragEnabled|QtCore.Qt.ItemIsUserCheckable|QtCore.Qt.ItemIsEnabled|QtCore.Qt.ItemIsTristate)
            elif qname == 'FeatureName':
                self._item.setText(1, self._text)
        self._text = ''
        return True

    def endElement(self, namespace, name, qname):
        if qname == 'FeatureName' or qname == 'MachineName':
            if self._item is not None:
                self._item.setText(0, self._text)
                self._item.setCheckState(0, QtCore.Qt.Unchecked)
        elif qname == 'Feature' or qname == 'Machine':
            self._item = self._item.parent()
        return True

    def characters(self, text):
        self._text += text
        return True

    def fatalError(self, exception):
        print('Parse Error: line %d, column %d:\n  %s' % (
              exception.lineNumber(),
              exception.columnNumber(),
              exception.message(),
              ))
        return False

使用XmlHandler制作小部件的类:

class MakeWidget(QtGui.QTreeWidget):
    def __init__(self):
        QtGui.QTreeWidget.__init__(self)
        self.header().setResizeMode(QtGui.QHeaderView.Stretch)
        self.setHeaderLabels(['Servers and Services'])
        source = QtXml.QXmlInputSource()
        source.setData(xml)
        handler = XmlHandler(self)
        reader = QtXml.QXmlSimpleReader()
        reader.setContentHandler(handler)
        reader.setErrorHandler(handler)
        reader.parse(source)

我摸索并尝试在我的 GUI 中使用它:

class Ui_MainWindow(object):

    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(950, 500)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
        MainWindow.setSizePolicy(sizePolicy)
        MainWindow.setMaximumSize(QtCore.QSize(950, 500))
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.tabWidget = QtGui.QTabWidget(self.centralwidget)
        self.tabWidget.setGeometry(QtCore.QRect(0, 0, 960, 421))
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed, QtGui.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.tabWidget.sizePolicy().hasHeightForWidth())
        self.tabWidget.setSizePolicy(sizePolicy)
        self.tabWidget.setMaximumSize(QtCore.QSize(960, 430))
        self.tabWidget.setAutoFillBackground(True)
        self.tabWidget.setStyleSheet(_fromUtf8(""))
        self.tabWidget.setObjectName(_fromUtf8("tabWidget"))
        self.tabLogPuller = QtGui.QWidget()
        self.tabLogPuller.setObjectName(_fromUtf8("tabLogPuller"))
        self.groupBoxServiceSelection = QtGui.QGroupBox(self.tabLogPuller)
        self.groupBoxServiceSelection.setGeometry(QtCore.QRect(0, 0, 381, 351))
        font = QtGui.QFont()
        font.setBold(False)
        font.setWeight(50)
        self.groupBoxServiceSelection.setFont(font)
        self.groupBoxServiceSelection.setAutoFillBackground(True)
        self.groupBoxServiceSelection.setObjectName(_fromUtf8("groupBoxServiceSelection"))
        self.treeServiceSelection = MakeWidget()
        self.treeServiceSelection.setHeaderLabels(['Servers and Services'])
        self.treeServiceSelection.source = QtXml.QXmlInputSource()
        self.treeServiceSelection.source.setData(xml)
        self.treeServiceSelection.handler = XmlHandler(self)
        self.treeServiceSelection.reader = QtXml.QXmlSimpleReader()
        self.treeServiceSelection.reader.setContentHandler(self.treeServiceSelection.handler)
        self.treeServiceSelection.reader.setErrorHandler(self.treeServiceSelection.handler)
        self.treeServiceSelection.reader.parse(self.treeServiceSelection.source)
        self.treeServiceSelection.setGeometry(QtCore.QRect(10, 80, 161, 261))
        self.treeServiceSelection.setObjectName(_fromUtf8("treeServiceSelection"))

以及我在尝试运行该文件时遇到的错误:

error triggered by consumer
    self._item = QtGui.QTreeWidgetItem(self._root)
TypeError: arguments did not match any overloaded call:
  QTreeWidgetItem(int type=QTreeWidgetItem.Type): argument 1 has unexpected type 'Ui_MainWindow'
  QTreeWidgetItem(list-of-str, int type=QTreeWidgetItem.Type): argument 1 has unexpected type 'Ui_MainWindow'
  QTreeWidgetItem(QTreeWidget, int type=QTreeWidgetItem.Type): argument 1 has unexpected type 'Ui_MainWindow'
  QTreeWidgetItem(QTreeWidget, list-of-str, int type=QTreeWidgetItem.Type): argument 1 has unexpected type 'Ui_MainWindow'
  QTreeWidgetItem(QTreeWidget, QTreeWidgetItem, int type=QTreeWidgetItem.Type): argument 1 has unexpected type 'Ui_MainWindow'
  QTreeWidgetItem(QTreeWidgetItem, int type=QTreeWidgetItem.Type): argument 1 has unexpected type 'Ui_MainWindow'
  QTreeWidgetItem(QTreeWidgetItem, list-of-str, int type=QTreeWidgetItem.Type): argument 1 has unexpected type 'Ui_MainWindow'
  QTreeWidgetItem(QTreeWidgetItem, QTreeWidgetItem, int type=QTreeWidgetItem.Type): argument 1 has unexpected type 'Ui_MainWindow'
  QTreeWidgetItem(QTreeWidgetItem): argument 1 has unexpected type 'Ui_MainWindow'

所以我想我的问题是:如何调用此类并在 UI_MainWindow 类中传递正确的参数,而不是调用我假设的父类?

最佳答案

您在此处创建 MakeWidget 的实例:

    self.treeServiceSelection = MakeWidget()

然后在其 __init__ 中设置 XmlReader 等。但是,神秘的是,您随后尝试在以下几行中重复这一切:

    self.treeServiceSelection.setHeaderLabels(['Servers and Services'])
    self.treeServiceSelection.source = QtXml.QXmlInputSource()
    self.treeServiceSelection.source.setData(xml)
    ...

你想在这里做什么?如果需要调整MakeWidget类的初始化,请修改其__init__中的代码。

实际错误是由这一行引起的:

    self.treeServiceSelection.handler = XmlHandler(self)

当需要 QTreeWidget 实例时,它将 Ui_MainWindow 实例传递给 XmlHandler 的构造函数。但如前所述,这实际上是无关紧要的,因为第一行后面的所有代码无论如何都是多余的。

看来更根本的问题是您试图直接编辑 pyuic 生成的 ui 文件而不是导入到您的应用程序中。生成的 ui 文件应被视为只读。永远、永远不要试图编辑它。

相反,您需要创建一个包含主窗口类的模块,该类执行如下操作:

from ui import Ui_MainWindow

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        ui = Ui_MainWindow()
        ui.setupUi(self)
        # other setup code goes here
        ...

我还建议您将 MakeWidget 类修改为如下所示:

class MakeWidget(QtGui.QTreeWidget):
    def __init__(self, xml, parent=None):
        QtGui.QTreeWidget.__init__(self, parent)

这样您就可以在 MainWindow.__init__ 中创建它的实例,如下所示:

        self.treeServiceSelection = MakeWidget(xml, self)

或者可能将 xml 解析代码分解为将 xml 作为参数的方法。

关于python - 调用类在窗口内构建QTreeWidget : argument 1 has unexpected type 'Ui_MainWindow' ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19775487/

相关文章:

python - 两个类似的实现退出运行时间差异巨大

python - 如何重写不在类中的核心Python函数

Python:有吸引力的、干净的、可打包的 Windows GUI 库

python - Pyqt5 QTreeWidget CurrentItemChanged 信号发送整数作为前一项

python - 在 QTreeWidget 中调用上下文菜单

python - 不同的整数组

python - PyQt4 : Connect splitter

python-3.x - 在另一台计算机上运行卡住的 pyqt 应用程序时不显示图像

PyQt4 - "RuntimeError: underlying C/C object has been deleted"

c++ - 如何将 itemExpanded 与 QTreeWidgetItem 的子类一起使用