从 PyQt5 中的另一个类访问变量

Posted

技术标签:

【中文标题】从 PyQt5 中的另一个类访问变量【英文标题】:Access A Variable from another class in PyQt5 【发布时间】:2021-01-12 15:54:03 【问题描述】:

在 PyQt5 中,我编写了一个 GUI。基本上,当按下按钮时,它会打开一个新窗口,从列表中选择一个项目。我想要的是,在您关闭新窗口后,您选择的项目在第一个窗口上显示为文本。这很难解释。

这是代码:

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont
from PyQt5 import QtWidgets
from PyQt5 import QtCore 
from PyQt5 import QtGui

class Add(QtWidgets.QMainWindow):
    def __init__(self):
        super(Add, self).__init__()

        #Set The UI
        self.initUI()
        #Set The GUI Position And Size
        self.setGeometry(1050, 500, 400, 50)
        #Set The GUI Title
        self.setWindowTitle("Add")
        
    def initUI(self):
        Central = QtWidgets.QWidget(self)
        self.setCentralWidget(Central)

        self.deckButton = QtWidgets.QPushButton(self)
        self.deckButton.setText("Choose")
        self.deckButton.clicked.connect(self.open_deck_browser)

        hbox = QtWidgets.QHBoxLayout()
        hbox.addWidget(self.deckButton, 1)

        Central.setLayout(hbox)

    def open_deck_browser(self):
        self.w = SetDeck()
        self.w.show()

class SetDeck(QtWidgets.QMainWindow):
    def __init__(self):
        super(SetDeck, self).__init__()

        #Set The UI
        self.initUI()
        #Set The GUI Position And Size
        self.setGeometry(200, 200, 800, 640)
        #Set The GUI Title
        self.setWindowTitle("Choose Deck")
        
    def initUI(self):
        widAddToDeckWindow = QtWidgets.QWidget(self)
        self.setCentralWidget(widAddToDeckWindow)

        #Create The List Widget
        self.deckList = QtWidgets.QListWidget()

        self.deckList.insertItem(0, "Hello")
        self.deckList.insertItem(1, "Hi")
        self.deckList.insertItem(2, "Hello There")

        self.deckList.item(0).setSelected(True)

        self.deckList.itemSelectionChanged.connect(self.show_List)
        print([x.row() for x in self.deckList.selectedIndexes()])

        #Create The Select Deck Button
        self.selectDeck = QtWidgets.QPushButton(self)
        self.selectDeck.setText("Choose")
        
        hboxCreateBottomButtons = QtWidgets.QHBoxLayout()

        hboxCreateBottomButtons.addStretch()
        hboxCreateBottomButtons.addWidget(self.selectDeck)

        #Create The Main VBox
        vboxMain = QtWidgets.QVBoxLayout()
        vboxMain.addWidget(self.deckList)
        vboxMain.addLayout(hboxCreateBottomButtons)        

        widAddToDeckWindow.setLayout(vboxMain)

    def show_List(self):
        print(repr(self.deckList.selectedItems()[0].text()))

def window():
    app = QtWidgets.QApplication(sys.argv)
    win = Add()
    win.show()
    sys.exit(app.exec_())

window()

我尝试过使用全局变量,但没有成功。

【问题讨论】:

【参考方案1】:

首先,我建议你在命名变量时改进你的风格,因为它们使阅读更容易,例如类名是名词而不是动词。

找出问题的根源,永远不要使用(或尝试使用)全局变量,因为如果有更好的选择并且您不了解它的工作原理,它们会导致静默错误。如果您想要一个窗口,要求用户提供有关如何选择将在主窗口中使用的选项的信息,那么建议使用 QDialog。在下面的示例中,这已完成,并且“选择”按钮链接到接受槽,以便它关闭窗口,并且该信息可用于知道窗口的“x”按钮没有关闭。我还创建了一个包含所选文本的属性。

import sys

from PyQt5 import QtCore, QtGui, QtWidgets


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.initUI()
        self.setGeometry(1050, 500, 400, 50)
        self.setWindowTitle("Add")

    def initUI(self):
        central = QtWidgets.QWidget(self)
        self.setCentralWidget(central)

        self.deckButton = QtWidgets.QPushButton()
        self.deckButton.setText("Choose")
        self.deckButton.clicked.connect(self.open_deck_browser)

        box = QtWidgets.QVBoxLayout(central)
        box.addWidget(self.deckButton)
        self.label = QtWidgets.QLabel()
        box.addWidget(self.label)
        self.label.hide()

    def open_deck_browser(self):
        dialog = DeckDialog()
        if dialog.exec_() == QtWidgets.QDialog.Accepted:
            self.label.show()
            self.label.setText(dialog.selected_text)


class DeckDialog(QtWidgets.QDialog):
    def __init__(self):
        super(DeckDialog, self).__init__()

        self.initUI()
        self.setGeometry(200, 200, 800, 640)
        self.setWindowTitle("Choose Deck")

    def initUI(self):
        self.deckList = QtWidgets.QListWidget()

        self.deckList.insertItem(0, "Hello")
        self.deckList.insertItem(1, "Hi")
        self.deckList.insertItem(2, "Hello There")

        self.deckList.item(0).setSelected(True)

        self.selectDeck = QtWidgets.QPushButton(self)
        self.selectDeck.setText("Choose")

        hboxCreateBottomButtons = QtWidgets.QHBoxLayout()

        hboxCreateBottomButtons.addStretch()
        hboxCreateBottomButtons.addWidget(self.selectDeck)

        vboxMain = QtWidgets.QVBoxLayout(self)
        vboxMain.addWidget(self.deckList)
        vboxMain.addLayout(hboxCreateBottomButtons)

        self.selectDeck.clicked.connect(self.accept)

    @property
    def selected_text(self):
        items = self.deckList.selectedItems()
        if items:
            return items[0].text()
        return ""


def main():
    app = QtWidgets.QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()

【讨论】:

非常感谢@eyllanesc。这很有帮助,但是有没有办法改变按钮文本而不是一个新变量,因为那是我最初的目标,但我无法很好地解释它。 @ThePilotDude 然后将 self.label.setText(dialog.selected_text) 更改为 self.deckButton.setText(dialog.selected_text)

以上是关于从 PyQt5 中的另一个类访问变量的主要内容,如果未能解决你的问题,请参考以下文章

仍然可以从 C# 中的另一个类访问私有变量

从java中的另一个类访问静态变量

从 Java Swing 中的另一个类访问 JPanel 变量

如何从 Swift SpriteKit 中的另一个 SKScene 访问变量

PyQt5 无法访问另一个类函数

从java中的另一个线程访问一个线程的变量