【问题标题】:Python PyQt - How to edit a variable in another function when function is run multiple timesPython PyQt - 当函数多次运行时如何在另一个函数中编辑变量
【发布时间】:2015-09-30 12:26:09
【问题描述】:

在我的 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

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

【问题讨论】:

  • 短版:使用self.editThisLine。更长的版本:read up on classes, instances, and instance properties.
  • 关于短版 - 返回错误:“'Example' 对象没有属性 'editThisLine'。关于长版 - 感谢链接!
  • 你必须在任何地方使用self.editThisLine——首先设置它,然后引用它。您不是创建一个函数本地的变量,而是创建一个实例属性。该链接应该有助于解释发生了什么。
  • 我添加了自己。在所有 editThisLine 之前,它现在编辑另一个选项卡,而不是单击按钮的选项卡。一旦我有更多时间,我会阅读更多文章。

标签: python python-3.x pyqt pyqt5


【解决方案1】:

您缺少的概念是closure。闭包用函数封装了作用域,因此函数中的代码可以访问该关联作用域内的变量。连接信号时使用闭包的最简单方法是使用lambda(尽管有些人更喜欢使用functools.partial)。

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

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

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

但是,我认为这可能是在您的代码中“掩盖裂缝”,并且可能不是最佳解决方案。更好的解决方案是正确使用类提供的命名空间。 addTheTabrunThisWhenButtonClicked 应重构为 Tab 类,该类将其所有子小部件作为属性:

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())

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

【讨论】:

    猜你喜欢
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-31
    • 1970-01-01
    • 1970-01-01
    • 2014-07-14
    相关资源
    最近更新 更多