QtDesigner(SourceForm、DestinationForm)に2つのウィンドウを作成し、それらの.uiページを変換するためにpyuic5を使用しました。私はスタックウィジェットを使用して2つのウィンドウ間を移動する方法として、第3のクラスWController
を使用しています。 SourceForm
には、treeWidget
に何らかのデータが入力され、handle_treewidget_itemchange
のメソッドは、self.treeWidget.itemChanged.connect(self.handle_treewidget_itemchange)
を使用してtreeWidget
の特定の項目をチェックするかチェックしないかを指定します。 itemChanged.connect
が自動的にスロットに変更されたかの行と列を送信することを私の理解だったが、handle_treewidget_itemchange(self,row,col)
が最初に呼び出されたときに、私のスクリプトは、TypeError例外でクラッシュ:私が取る場合PyQt5初心者 - シグナルと欠落した位置引数
TypeError: handle_treewidget_itemchange() missing 2 required positional arguments: 'row' and 'col'
row
とcol
argsの場合、スクリプトはうまく動作します。もともと私はSourceForm
.pyファイル自体にメソッドと呼び出しの両方を持っていましたが、私のコードは意図したとおりに動作しました...これは単なるスコープの問題ですか?
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_())
pyqtSlotが本当のQtのスロットを作成します。
を使用すると、1つの接続または他を有効にすることができ、このコードを参照してください、そして窓がガベージコレクトできるか否かを示す動作の違いを観察しますスロットを持つQObjectが破壊/ガベージコレクトされると(Qtは削除されたQObjectから何かを切断する)、接続は切断されます。 '@ pyqtSlot'を使わない場合、接続はQObjectを追跡することができないので、呼び出し可能な参照を保持してQObjectへの参照を保持し、破壊。 IMHO可能であれば '@ pyqtSlot'を使うのが好きです。 –
ああ、恥ずかしいです、それは今働いています!どうもありがとうございます! '@pyqtSlot()'デコレータを使用していたので、簡単にスロットを見つけることができました。私(危険な)はそれがその形で良性であると仮定した。 私はもともと 'handle_treewidget_itemchange'メソッドとその接続ステートメントを' SourceForm'に入れました(GUIを微調整したいと思ってすぐに学んだのは恐ろしいアイデアでした)。そして、スロットは行と列の引数を 'pyqtslot 'デコレータはそのままです...だから私はそれを潜在的な修正として削除することは考えていませんでした。 –
私はちょうど私が言ったことをテストしました:実際のスロットに接続するhttp://pastebin.com/W5tFkWGLは、 "任意の呼び出し可能"をスロットとして使用するのとは異なり、参照カウントを妨げません。ですから、私は本当に "呼び出し可能"を 'connect'のターゲットとして使うのは悪い考えです。可能ならば避け、' pyqtSlot'で置き換えるのが良いと思います。 –