【发布时间】:2016-07-15 15:36:40
【问题描述】:
我在 QtDesigner 中开发了两个窗口(SourceForm、DestinationForm)并使用 pyuic5 来转换它们的 .ui 页面。我正在使用第三类WController 作为使用堆叠小部件在两个窗口之间导航的一种方式。我在SourceForm 中有一个按钮,它用一些数据填充treeWidget,handle_treewidget_itemchange 方法指示当treeWidget 中的特定项目通过使用self.treeWidget.itemChanged.connect(self.handle_treewidget_itemchange) 被选中或取消选中时会发生什么。我的理解是itemChanged.connect 会自动将更改的行和列发送到插槽,但是当handle_treewidget_itemchange(self,row,col) 第一次被调用时,我的脚本会因 TypeError 而崩溃:
TypeError: handle_treewidget_itemchange() missing 2 required positional arguments: 'row' and 'col'
如果我取出 row 和 col 参数,脚本运行良好。当我最初在 SourceForm .py 文件本身中同时拥有方法和调用时,我的代码按预期工作......也许这只是一个范围问题?我开始认为尝试使用 PyQt 而对 Python 仍然缺乏经验是个坏主意:(
我已尝试将代码精简到基本要素:
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtCore import pyqtSlot
from imp_sourceform import Ui_SourceForm
from imp_destform import Ui_DestinationForm
class WController(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(WController, self).__init__(parent)
self.central_widget = QtWidgets.QStackedWidget()
self.setCentralWidget(self.central_widget)
self.sourcewindow = SourceForm()
self.destinationwindow = DestinationForm()
self.central_widget.addWidget(self.sourcewindow)
self.central_widget.addWidget(self.destinationwindow)
self.central_widget.setCurrentWidget(self.sourcewindow)
self.sourcewindow.selectdestinationsbutton.clicked.connect(lambda: self.navigation_control(1))
self.destinationwindow.backbutton.clicked.connect(lambda: self.navigation_control(0))
def navigation_control(self, topage):
if topage == 1:
self.central_widget.setCurrentWidget(self.destinationwindow)
elif topage == 0:
self.central_widget.setCurrentWidget(self.sourcewindow)
class SourceForm(QtWidgets.QWidget, Ui_SourceForm):
def __init__(self):
super(SourceForm, self).__init__()
self.setupUi(self)
self.treeWidget.itemChanged.connect(self.handle_treewidget_itemchange)
@pyqtSlot()
def handle_treewidget_itemchange(self,row,col):
if row.parent() is None and row.checkState(col) == QtCore.Qt.Unchecked:
for x in range(0,row.childCount()):
row.child(x).setCheckState(0, QtCore.Qt.Unchecked)
elif row.parent() is None and row.checkState(col) == QtCore.Qt.Checked:
for x in range(0,row.childCount()):
row.child(x).setCheckState(0, QtCore.Qt.Checked)
else:
pass
class DestinationForm(QtWidgets.QWidget, Ui_DestinationForm):
def __init__(self):
super(DestinationForm, self).__init__()
self.setupUi(self)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
window = WController()
window.show()
sys.exit(app.exec_())
【问题讨论】:
-
有趣的是,无论函数定义如何,PySide2 都可以使用不带参数的 @Slot() 装饰,但 PyQt5 不能,正如我在从 PySide2 迁移到 PyQt5 期间发现的那样。感谢这个答案引导我找到我的问题和解决方案。