Python PyQt - 如何在函数多次 运行 时编辑另一个函数中的变量

Python PyQt - How to edit a variable in another function when function is run multiple times

在我的 PyQt5 程序中,我有选项卡并使用一个函数多次创建相同的选项卡。在 PyQt 中,要在单击按钮时编写 运行 代码,您需要将其连接到另一个函数。在 createATab 函数中,我有一个 QLineEdit 需要在单击按钮时进行编辑。这是我正在尝试做的一个例子:

class Example(QWidget, QWindow):
    def __init__(self):
        super().__init__()

        self.initUI()
    def runThisWhenButtonClicked(self):
        getText = editThisLine.text()
        editThisLine.clear() # edits variable in other function except other function is run multiple times
    def addTheTab(self, username):
        addingTab = QWidget()
        aButton = QPushButton("Stuff")
        editThisLine = QLineEdit()
        aButton.clicked.connect(self.runThisWhenButtonClicked)
        tabGrid = QGridLayout(addingTab)
        tabGrid.addWidget(editThisLine, 3, 1, 4, 2)
        tabGrid.addWidget(aButton, 3, 3, 4, 3)
        tab_widget.addTab(addingTab, str(username))    

    def initUI(self):
        global tab_widget
        tab_widget = QTabWidget()
        listwidget = QListWidget()
        listwidget.itemDoubleClicked.connect(self.addTheTab)
        splitterrr = QSplitter()
        splitterrr.addWidget(listwidget)
        splitterrr.addWidget(tab_widget)
        QListWidgetItem("Test1", listwidget)
        QListWidgetItem("Test2", listwidget)
        mainLayout = QHBoxLayout()
        mainLayout.addWidget(splitterrr)
        self.setLayout(mainLayout)
        self.setGeometry(300, 300, 300, 300)
        self.setWindowTitle('Test')
        self.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

How do I pass a variable by reference?

我已经通读了这个,虽然它确实解释了很多,但没有解释如何解决这个问题。

pyqt4 button click handler

这解释了您如何只传递函数,而不是调用它。因此,无法将变量传递给 运行ThisWhenButtonClicked 函数。

您缺少的概念是 closure. A closure wraps up a scope with a function, so that code in the function can access variables within that associated scope. The simplest way to utilise closures when connecting signals is with a lambda (although some people prefer to use functools.partial)。

在您的示例中,这意味着像这样连接信号:

    aButton.clicked.connect(lambda: self.runThisWhenButtonClicked(editThisLine))
    ...

def runThisWhenButtonClicked(self, editThisLine):
    print(editThisLine.text())

但是,我认为这可能是您代码中的 "papering over the cracks",并且可能不是最佳解决方案。更好的解决方案是正确使用 classes 提供的命名空间。 addTheTabrunThisWhenButtonClicked 应该重构为 Tab class,它的所有子部件都作为属性:

class Tab(QWidget):
    def __init__(self, parent=None):
        super(Tab, self).__init__(parent)
        self.editThisLine = QLineEdit()
        self.aButton = QPushButton("Stuff")
        self.aButton.clicked.connect(self.runThisWhenButtonClicked)
        ...

    def runThisWhenButtonClicked(self):
        print(self.editThisLine.text())

这将完全消除您示例中对闭包的需要。