使用 QDialog 中的 QPushButton 更新 QLabel
Update a QLabel , using a QPushButton in a QDialog
我刚开始使用 PyQt5,我正在尝试通过子类 (QDialog) 中的按钮更新标签的信息。当我按下按钮时,程序停止并显示消息:
"AttributeError: 'New_Player_Window' object has no attribute 'name_window_label'
想法是当按下按钮时,默认为 "Anonimous" 的 Qlabel 成为用户的名称。
密码是:
from PyQt5 import QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout,
QLineEdit, QLabel, QWidget, QPushButton, QMessageBox, QAction, QMenu,
QDialog
import sys
class General_Window(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.resize(500, 500)
self.move(300, 100)
self.setWindowTitle('Black Jack')
#MENUBAR
menubar = self.menuBar()
fileMenu = menubar.addMenu('File')
newAct = QAction('New Player', self)
newAct.triggered.connect(General_Window.new_player)
fileMenu.addAction(newAct)
#LABEL
self.name_window_label = QLabel('Anonimous', self)
self.name_window_label.move(245, 15)
self.show()
def update_window(self, value):
print(str(value))
self.name_window_label.setText(str(value))
def new_player(self):
class New_Player_Window(QDialog, General_Window):
def __init__(self):
super().__init__()
self.initUI()
def create(self):
try:
int(self.money.text()) + 2
except:
QMessageBox.question(self, 'PyQt5 message', "You need to
insert a Number", QMessageBox.Ok , QMessageBox.Ok)
else:
global value
value = self.name.text()
print(value)
self.update_window(value)
def initUI(self):
self.setGeometry(300, 230, 250, 120)
self.setWindowTitle('User Information')
#TEXTBOX1
self.name = QLineEdit(self)
self.name.move(110, 5)
self.name.resize(110,20)
#TEXTBOX2
self.money = QLineEdit(self)
self.money.move(110, 40)
self.money.resize(110,20)
#BUTTON1
self.button = QPushButton('Create', self)
self.button.move(5,80)
self.button.clicked.connect(self.create)
#BUTTON2
self.button2 = QPushButton('Cancel', self)
self.button2.move(120,80)
#LABELNAME
self.name_label = QLabel('SHORT NAME', self)
self.name_label.move(20,10)
#LABELNAME
self.money_label = QLabel('MONEY AVAILABLE', self)
self.money_label.move(10,45)
self.show()
self.exec_()
if __name__=="__main__":
New_Player_Window()
if __name__=="__main__":
app = QApplication(sys.argv)
ag = General_Window()
sys.exit(app.exec_())
试一试:
import sys
from PyQt5 import QtGui, QtWidgets
from PyQt5.QtWidgets import (QApplication, QMainWindow, QVBoxLayout,
QLineEdit, QLabel, QWidget, QPushButton,
QMessageBox, QAction, QMenu, QDialog, QSpinBox)
class General_Window(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.resize(500, 500)
self.move(300, 100)
self.setWindowTitle('Black Jack')
#MENUBAR
menubar = self.menuBar()
fileMenu = menubar.addMenu('File')
newAct = QAction('New Player', self)
newAct.triggered.connect(self.new_player)
fileMenu.addAction(newAct)
#LABEL
self.name_window_label = QLabel('Anonimous', self)
self.name_window_label.move(245, 15)
def update_window(self, value):
print(str(value))
self.name_window_label.setText(str(value))
def new_player(self):
self.newPlayerWindow = New_Player_Window(self)
class New_Player_Window(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.parent = parent
self.value = 12
self.initUI()
def create(self):
value = "{} - {}".format(self.name.text(), self.value)
print(value)
self.parent.update_window(value)
self.close()
def initUI(self):
self.setGeometry(300, 230, 250, 120)
self.setWindowTitle('User Information')
#TEXTBOX1
self.name = QLineEdit(self)
self.name.move(110, 5)
self.name.resize(110,20)
#TEXTBOX2
self.money = QSpinBox(self) #QLineEdit(self)
self.money.setRange(1, 99)
self.money.setValue(12)
self.money.valueChanged.connect(self.moneyValueChanged)
self.money.move(110, 40)
self.money.resize(110,20)
#BUTTON1
self.button = QPushButton('Create', self)
self.button.move(5,80)
self.button.clicked.connect(self.create)
#BUTTON2
self.button2 = QPushButton('Cancel', self)
self.button2.move(120,80)
#LABELNAME
self.name_label = QLabel('SHORT NAME', self)
self.name_label.move(20,10)
#LABELNAME
self.money_label = QLabel('MONEY AVAILABLE', self)
self.money_label.move(10,45)
self.exec_()
def moneyValueChanged(self, value):
self.value = value
if __name__=="__main__":
app = QApplication(sys.argv)
ag = General_Window()
ag.show()
sys.exit(app.exec_())
您有几个错误:
正如您指出的那样,General_Window 具有 name_window_label 属性,因此预计 New_Player_Window 也会具有它,但是 name_window_label是在 initUI 中创建的,但您已经在 New_Player_Window class 中覆盖了它,因此该属性不存在,但即使它有它,它也不会是另一个 [=] 的 name_window_label 49=] 因为它是另一个具有另一个对象的 class,我建议阅读有关 OOP 的内容,尤其是有关继承和组合的内容。
拥有另一个 class 的内部 class 被认为是一种不好的做法(django 等除外),因为您每时每刻都在创建 class不必要地花费资源。
这本身不是错误,而是一种不好的做法,不要使用全局变量,因为调试全局变量很复杂,因为它的生命周期很困难,可以隐藏其他类型的问题。
最后考虑使用适当的小部件让用户输入适当的数据类型,例如对整数值使用 QSpinBox 以避免不必要的检查。我还将建议添加到布局的使用中,因为我将在我的回答中显示。
转到解决方案的设计,当您创建小部件时,将其视为接收输入并生成输出的黑盒,如果输出是同步的,它会使用一种方法,您可以在其中检索该信息,如果是异步它使用一个信号,在 QDialog 的另一端是一个 class 专门用于请求信息,所以你不应该更新 New_Player_Window 中的信息,但在 General_Window 中你必须传递信息。如果用户接受或拒绝请求,QDialog 使用 exec_()
到 return 但为此您必须调用接受或拒绝。
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class New_Player_Window(QtWidgets.QDialog):
def __init__(self):
super().__init__()
self.initUI()
def get_values(self):
return self.name.text(), self.money.value()
def initUI(self):
self.setWindowTitle('User Information')
#TEXTBOX1
self.name = QtWidgets.QLineEdit()
#TEXTBOX2
self.money = QtWidgets.QSpinBox(maximum=2147483647)
#BUTTON1
self.button = QtWidgets.QPushButton('Create')
self.button.clicked.connect(self.accept)
#BUTTON2
self.button2 = QtWidgets.QPushButton('Cancel')
self.button2.clicked.connect(self.reject)
lay = QtWidgets.QVBoxLayout(self)
flay = QtWidgets.QFormLayout()
flay.addRow("SHORT NAME", self.name)
flay.addRow("MONEY AVAILABLE", self.money)
lay.addLayout(flay)
hlay = QtWidgets.QHBoxLayout()
hlay.addWidget(self.button)
hlay.addWidget(self.button2)
lay.addLayout(hlay)
self.setFixedSize(self.sizeHint())
class General_Window(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('Black Jack')
#MENUBAR
menubar = self.menuBar()
fileMenu = menubar.addMenu('File')
newAct = QtWidgets.QAction('New Player', self)
newAct.triggered.connect(self.new_player)
fileMenu.addAction(newAct)
#LABEL
self.name_window_label = QtWidgets.QLabel('Anonimous', alignment=QtCore.Qt.AlignCenter)
widget = QtWidgets.QWidget()
self.setCentralWidget(widget)
lay = QtWidgets.QVBoxLayout(widget)
lay.addWidget(self.name_window_label, alignment=QtCore.Qt.AlignTop)
def update_window(self, value):
self.name_window_label.setText(value)
def new_player(self):
w = New_Player_Window()
if w.exec_() == QtWidgets.QDialog.Accepted:
name, value = w.get_values()
print(name, value)
self.update_window(name)
if __name__=="__main__":
app = QtWidgets.QApplication(sys.argv)
ag = General_Window()
ag.show()
sys.exit(app.exec_())
我刚开始使用 PyQt5,我正在尝试通过子类 (QDialog) 中的按钮更新标签的信息。当我按下按钮时,程序停止并显示消息:
"AttributeError: 'New_Player_Window' object has no attribute 'name_window_label'
想法是当按下按钮时,默认为 "Anonimous" 的 Qlabel 成为用户的名称。
密码是:
from PyQt5 import QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout,
QLineEdit, QLabel, QWidget, QPushButton, QMessageBox, QAction, QMenu,
QDialog
import sys
class General_Window(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.resize(500, 500)
self.move(300, 100)
self.setWindowTitle('Black Jack')
#MENUBAR
menubar = self.menuBar()
fileMenu = menubar.addMenu('File')
newAct = QAction('New Player', self)
newAct.triggered.connect(General_Window.new_player)
fileMenu.addAction(newAct)
#LABEL
self.name_window_label = QLabel('Anonimous', self)
self.name_window_label.move(245, 15)
self.show()
def update_window(self, value):
print(str(value))
self.name_window_label.setText(str(value))
def new_player(self):
class New_Player_Window(QDialog, General_Window):
def __init__(self):
super().__init__()
self.initUI()
def create(self):
try:
int(self.money.text()) + 2
except:
QMessageBox.question(self, 'PyQt5 message', "You need to
insert a Number", QMessageBox.Ok , QMessageBox.Ok)
else:
global value
value = self.name.text()
print(value)
self.update_window(value)
def initUI(self):
self.setGeometry(300, 230, 250, 120)
self.setWindowTitle('User Information')
#TEXTBOX1
self.name = QLineEdit(self)
self.name.move(110, 5)
self.name.resize(110,20)
#TEXTBOX2
self.money = QLineEdit(self)
self.money.move(110, 40)
self.money.resize(110,20)
#BUTTON1
self.button = QPushButton('Create', self)
self.button.move(5,80)
self.button.clicked.connect(self.create)
#BUTTON2
self.button2 = QPushButton('Cancel', self)
self.button2.move(120,80)
#LABELNAME
self.name_label = QLabel('SHORT NAME', self)
self.name_label.move(20,10)
#LABELNAME
self.money_label = QLabel('MONEY AVAILABLE', self)
self.money_label.move(10,45)
self.show()
self.exec_()
if __name__=="__main__":
New_Player_Window()
if __name__=="__main__":
app = QApplication(sys.argv)
ag = General_Window()
sys.exit(app.exec_())
试一试:
import sys
from PyQt5 import QtGui, QtWidgets
from PyQt5.QtWidgets import (QApplication, QMainWindow, QVBoxLayout,
QLineEdit, QLabel, QWidget, QPushButton,
QMessageBox, QAction, QMenu, QDialog, QSpinBox)
class General_Window(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.resize(500, 500)
self.move(300, 100)
self.setWindowTitle('Black Jack')
#MENUBAR
menubar = self.menuBar()
fileMenu = menubar.addMenu('File')
newAct = QAction('New Player', self)
newAct.triggered.connect(self.new_player)
fileMenu.addAction(newAct)
#LABEL
self.name_window_label = QLabel('Anonimous', self)
self.name_window_label.move(245, 15)
def update_window(self, value):
print(str(value))
self.name_window_label.setText(str(value))
def new_player(self):
self.newPlayerWindow = New_Player_Window(self)
class New_Player_Window(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.parent = parent
self.value = 12
self.initUI()
def create(self):
value = "{} - {}".format(self.name.text(), self.value)
print(value)
self.parent.update_window(value)
self.close()
def initUI(self):
self.setGeometry(300, 230, 250, 120)
self.setWindowTitle('User Information')
#TEXTBOX1
self.name = QLineEdit(self)
self.name.move(110, 5)
self.name.resize(110,20)
#TEXTBOX2
self.money = QSpinBox(self) #QLineEdit(self)
self.money.setRange(1, 99)
self.money.setValue(12)
self.money.valueChanged.connect(self.moneyValueChanged)
self.money.move(110, 40)
self.money.resize(110,20)
#BUTTON1
self.button = QPushButton('Create', self)
self.button.move(5,80)
self.button.clicked.connect(self.create)
#BUTTON2
self.button2 = QPushButton('Cancel', self)
self.button2.move(120,80)
#LABELNAME
self.name_label = QLabel('SHORT NAME', self)
self.name_label.move(20,10)
#LABELNAME
self.money_label = QLabel('MONEY AVAILABLE', self)
self.money_label.move(10,45)
self.exec_()
def moneyValueChanged(self, value):
self.value = value
if __name__=="__main__":
app = QApplication(sys.argv)
ag = General_Window()
ag.show()
sys.exit(app.exec_())
您有几个错误:
正如您指出的那样,General_Window 具有 name_window_label 属性,因此预计 New_Player_Window 也会具有它,但是 name_window_label是在 initUI 中创建的,但您已经在 New_Player_Window class 中覆盖了它,因此该属性不存在,但即使它有它,它也不会是另一个 [=] 的 name_window_label 49=] 因为它是另一个具有另一个对象的 class,我建议阅读有关 OOP 的内容,尤其是有关继承和组合的内容。
拥有另一个 class 的内部 class 被认为是一种不好的做法(django 等除外),因为您每时每刻都在创建 class不必要地花费资源。
这本身不是错误,而是一种不好的做法,不要使用全局变量,因为调试全局变量很复杂,因为它的生命周期很困难,可以隐藏其他类型的问题。
最后考虑使用适当的小部件让用户输入适当的数据类型,例如对整数值使用 QSpinBox 以避免不必要的检查。我还将建议添加到布局的使用中,因为我将在我的回答中显示。
转到解决方案的设计,当您创建小部件时,将其视为接收输入并生成输出的黑盒,如果输出是同步的,它会使用一种方法,您可以在其中检索该信息,如果是异步它使用一个信号,在 QDialog 的另一端是一个 class 专门用于请求信息,所以你不应该更新 New_Player_Window 中的信息,但在 General_Window 中你必须传递信息。如果用户接受或拒绝请求,QDialog 使用 exec_()
到 return 但为此您必须调用接受或拒绝。
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class New_Player_Window(QtWidgets.QDialog):
def __init__(self):
super().__init__()
self.initUI()
def get_values(self):
return self.name.text(), self.money.value()
def initUI(self):
self.setWindowTitle('User Information')
#TEXTBOX1
self.name = QtWidgets.QLineEdit()
#TEXTBOX2
self.money = QtWidgets.QSpinBox(maximum=2147483647)
#BUTTON1
self.button = QtWidgets.QPushButton('Create')
self.button.clicked.connect(self.accept)
#BUTTON2
self.button2 = QtWidgets.QPushButton('Cancel')
self.button2.clicked.connect(self.reject)
lay = QtWidgets.QVBoxLayout(self)
flay = QtWidgets.QFormLayout()
flay.addRow("SHORT NAME", self.name)
flay.addRow("MONEY AVAILABLE", self.money)
lay.addLayout(flay)
hlay = QtWidgets.QHBoxLayout()
hlay.addWidget(self.button)
hlay.addWidget(self.button2)
lay.addLayout(hlay)
self.setFixedSize(self.sizeHint())
class General_Window(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.setWindowTitle('Black Jack')
#MENUBAR
menubar = self.menuBar()
fileMenu = menubar.addMenu('File')
newAct = QtWidgets.QAction('New Player', self)
newAct.triggered.connect(self.new_player)
fileMenu.addAction(newAct)
#LABEL
self.name_window_label = QtWidgets.QLabel('Anonimous', alignment=QtCore.Qt.AlignCenter)
widget = QtWidgets.QWidget()
self.setCentralWidget(widget)
lay = QtWidgets.QVBoxLayout(widget)
lay.addWidget(self.name_window_label, alignment=QtCore.Qt.AlignTop)
def update_window(self, value):
self.name_window_label.setText(value)
def new_player(self):
w = New_Player_Window()
if w.exec_() == QtWidgets.QDialog.Accepted:
name, value = w.get_values()
print(name, value)
self.update_window(name)
if __name__=="__main__":
app = QtWidgets.QApplication(sys.argv)
ag = General_Window()
ag.show()
sys.exit(app.exec_())