【问题标题】:PYQT5 update Label in 2nd window everytime variable changes每次变量更改时,PYQT5 在第二个窗口中更新标签
【发布时间】:2019-11-29 23:16:16
【问题描述】:

所以我想在我的第二个窗口 (= moneywindow1) 中显示一个全局变量 (= currenteMoney)。它工作正常,但每次我在主窗口中更改变量的值时,在我的第二个窗口中显示变量的标签应该更新。

from cheatwindow import cheatwindow1
from moneywindow import moneywindow1
import globals

class MyWindow(QMainWindow):
    def __init__(self):
        super(MyWindow, self).__init__()
        self.cheatwindow1 = None
        self.moneywindow1 = None
        self.setGeometry(600, 200, 800, 600)
        self.setWindowTitle("MyMainWindow")
        self.initUI()

    def initUI(self):
        globals.global_vars()

        mainMenu = self.menuBar()
        fileMenu = mainMenu.addMenu('File')
        save = QAction('New', self)
        save.setShortcut("Ctrl+S")
        save.triggered.connect(lambda: self.clicked_menu(0))
        load = QAction('Load', self)
        load.setShortcut("Ctrl+L")
        load.triggered.connect(lambda: self.clicked_menu(1))
        fileMenu.addAction(save)
        fileMenu.addAction(load)

        specialsMenu = mainMenu.addMenu('Specials')
        cheats = QAction("cheats", self)
        cheats.setShortcut("Ctrl+C")
        cheats.triggered.connect(lambda: self.clicked_menu(2))
        specialsMenu.addAction(cheats)

# Button that if clicked changes the variable
        self.ButtonThrow = QtWidgets.QPushButton(self)
        self.ButtonThrow.setText("Roll dice")
        self.ButtonThrow.move(300, 300)
        self.ButtonThrow.adjustSize()
        self.ButtonThrow.setEnabled(True)
        self.ButtonThrow.clicked.connect(lambda: self.throw_dice(0))

    def clicked_menu(self, a):
        if a == 0:
            print("Save")
        elif a == 1:
            self.money_popup()
        elif a== 2:
            self.cheat_popup()
        else:
            pass

# def that changes the variable
    def throw_dice(self, a):
        if a == 0:
            self.ButtonThrow.setEnabled(False)
            globals.currentThrow = random.randint(1, globals.diceMax)
            globals.currentMoney += globals.currentThrow*globals.diceCount
            QTimer.singleShot(globals.cdThrow*1000, lambda: 
        self.ButtonThrow.setEnabled(True))
        elif a == 1:
            pass
        self.labelWürfelpoints.setText("Letzer Wurf: " + 
               str(globals.currentThrow) + "\n" + "Gesamtpunktzahl: "+ 
               str(globals.currentMoney))
        self.labelWürfelpoints.adjustSize()

# Opens the 2.nd window
    def money_popup(self):
        if self.moneywindow1 is None:
            self.moneywindow1 = moneywindow1()
        self.moneywindow1.show()
        self.moneywindow1.activateWindow()


    def cheat_popup(self):
        if self.cheatwindow1 is None:
            self.cheatwindow1 = cheatwindow1()
        self.cheatwindow1.show()
        self.cheatwindow1.activateWindow()

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

window()

显示变量的第二个窗口的脚本:

import globals

class moneywindow1(QDialog):
    def __init__(self):
        super(moneywindow1, self).__init__()
        self.setGeometry(800, 400, 250, 200)
        self.setWindowTitle("MONEY")
        self.setupUi()

    def setupUi(self):
        globals.global_vars()

        self.label1 = QtWidgets.QLabel(self)
        font = QtGui.QFont()
        font.setPointSize(14)
        self.label1.setFont(font)
        self.label1.move(100, 80)
        self.label1.setText(str(globals.currentMoney))
        self.label1.adjustSize()

# def that updates the lable so the current value of the variable is displayed
    def moneywin_updater(self):
        self.label1.setText(str(globals.currentMoney))
        self.label1.adjustSize()

if __name__ == "__main__":
    import sys
    app2 = QApplication(sys.argv)
    win2 = moneywindow1()
    win2.show()
    sys.exit(app2.exec_())

问题是,我的变量(= currentMoney)也可以在我的第三个窗口(= cheatwindow1)中更改,因此很高兴找到一个不绑定到仅在主窗口中完成的更改的通用解决方案。顺便说一句,“import globals”脚本在这里:

def global_vars():
    global currentMoney
    currentMoney = 0

【问题讨论】:

  • 您在代码中的何处更改此变量?在任何情况下,您都不应该为此使用全局变量。向其他小部件广播数据的标准方法是使用信号和插槽。
  • 好的,我将 Button 和 def 编辑到上面的脚本中,该脚本更改了变量。我刚刚用谷歌搜索了什么是信号和插槽,我认为这就是我在脚本中所做的。你能给我一个例子来说明你的意思吗? :) 并且该变量是全局的,因为它在不同的窗口中使用,如果在一个窗口中更改它,它会在所有其他窗口中自动更改。(= sry 我是 python 新手,这种方法可能效率低下)。

标签: python-3.x pyqt5


【解决方案1】:

这是您的代码的精简版本,以说明我的意思。当前金额存储在MyWindow 的实例变量中。我还创建了一个信号MyWindow.money_changed,每次掷骰子并更改金额时都会发出该信号。通过将此信号连接到self.moneywindow.moneywin_updater,每次在第一个窗口中掷骰子时,第二个窗口中的标签都会自动更新。

from PyQt5 import QtWidgets, QtCore
from PyQt5.QtCore import Qt
import random

class moneywindow1(QtWidgets.QDialog):
    def __init__(self, parent = None):
        super().__init__(parent)
        self.setWindowTitle("MONEY")
        self.move(500,500)
        self.setupUi()

    def setupUi(self):
        self.label1 = QtWidgets.QLabel('', self)
        layout = QtWidgets.QHBoxLayout(self)
        layout.addWidget(self.label1, alignment=QtCore.Qt.AlignCenter)

    def moneywin_updater(self, amount):
        self.label1.setText(f'Current amount of money is {amount}')
        self.update()
        self.show()

class MyWindow(QtWidgets.QWidget):
    money_changed = QtCore.pyqtSignal(int)

    def __init__(self):
        super().__init__()
        self.setupUi()

        # create a moneywindow1 dialog and connect moneywin_updater to the signal money_changed
        self.moneywindow = moneywindow1(self)
        self.money_changed.connect(self.moneywindow.moneywin_updater)

        self.diceMax = 6
        self.currentMoney = 0

    def setupUi(self):
        self.label = QtWidgets.QLabel('Click button to roll dice', self)
        self.label.setAlignment(Qt.AlignCenter)
        self.button = QtWidgets.QPushButton('Roll', self)

        vlayout = QtWidgets.QVBoxLayout(self)
        vlayout.setAlignment(Qt.AlignCenter)
        vlayout.addWidget(self.label)
        vlayout.addWidget(self.button)

        self.button.clicked.connect(self.throw_dice)

    def throw_dice(self, a):
        currentThrow = random.randint(1, self.diceMax)
        self.currentMoney += currentThrow
        self.label.setText(f"Letzer Wurf: {currentThrow}\nGesamtpunktzahl: {self.currentMoney}")
        self.money_changed.emit(self.currentMoney)
        if not self.moneywindow.isVisible():
            self.moneywindow.show()


if __name__ == "__main__" :
    app = QtWidgets.QApplication([])
    win = MyWindow()
    win.show()
    app.exec()

【讨论】:

  • 嗯我不确定这是否有太多要问的问题,但你能解释一下为什么脚本知道,moneywin_updater 中的“金额”等于变量“currentMoney”吗?我找不到您定义金额 = currentMoney 的行
  • 无论何时发出信号,连接到该信号的任何槽都将被自动调用,其中随信号发出的值用作其参数。在这种情况下,money_changedself.currentMoney 的新值发出。这将触发对moneywindow.moneywin_updater 的调用,其中amount 将等于money_changed 发出的值,即self.currentMoney
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-11-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多