【问题标题】:I lose my settings of labels after switching between two windows在两个窗口之间切换后,我失去了标签设置
【发布时间】:2021-07-19 00:51:51
【问题描述】:

在上周搜索和谷歌搜索后,我尝试将 now 类与 PyQt5 一起使用。

我有两个窗口。一个是 MainWindow,另一个是 PrefWindow。 每个 GUI 上都有两个按钮和一个带有文本的标签。 使用第一个按钮,我可以更改标签文本及其背景颜色。

我使用第二个按钮更改 GUI 并转到 PrefWindow

在另一个 GUI PrefWindow 上也是如此。 我可以使用第二个按钮更改标签的文本和背景颜色 我回到主窗口。

问题是 MainWindow 上的更改在从 PrefWindow 返回后消失了。 我试图保存每个窗口标签的文本和背景颜色 但它会崩溃,并在下方显示 QLabel 已被删除的错误消息。为什么会崩溃?

错误信息:

Traceback(最近一次调用最后一次):文件 “C:/Users/m.owzar/PycharmProjects/Relais_Tester/Question.py”,行 132、在ChangeToMainWindow MainWindow().lbl_1.setText(lab_text_1) RuntimeError: QLabel 类型的包装 C/C++ 对象已被删除 已包装的 QLabel 类型的 C/C++ 对象 删除 进程完成并退出 代码 1

我的代码如下:

from PyQt5.QtWidgets import *
from PyQt5.QtGui import *

lab_text_1 = ''
lab_bg_color_1 = ''

lab_text_2 = ''
lab_bg_color_2 = ''

class MainWindow(QWidget):
    def __init__( self ):
        super().__init__()

        self.setGeometry(100, 100, 500, 400)
        self.setWindowTitle("Saving Window status")
        
        self.createMainWindow()

    def createMainWindow( self ):

        self.vbox_1 = QVBoxLayout()

        self.lbl_1 = QLabel('Label 1 Init')
        self.lbl_1.move(50, 50)
        self.lbl_1.setStyleSheet('font-size: 13pt; color: blue; background-color:lightgreen; font-weight: bold;')


        self.btnChange_1 = QPushButton("Change Label Text")
        self.btnChange_1.setFixedSize(200, 50)
        self.btnChange_1.clicked.connect(self.chaneLabelText_1)
        self.btnChange_1.setStyleSheet('font-size: 12pt; color: blue; background-color:lightcyan; font-weight: bold;')

        self.btnSettings = QPushButton("Settings")
        self.btnSettings.setFixedSize(200, 50)
        self.btnSettings.clicked.connect(self.ChangeToPrefWindow)
        self.btnSettings.setStyleSheet('font-size: 12pt; color: blue; background-color:lightcyan; font-weight: bold;')

        self.vbox_1.addWidget(self.lbl_1)
        self.vbox_1.addWidget(self.btnChange_1)
        self.vbox_1.addWidget(self.btnSettings)

        self.setLayout(self.vbox_1)

    def chaneLabelText_1(self):
        print('Label Text before: ' + self.lbl_1.text())
        self.lbl_1.setText('Labl 1 is new.\nIts Background color is also new!')
        print('Label Text after:  ' + self.lbl_1.text())

        lbl_1_bg_color = self.lbl_1.palette().color(QPalette.Base).name()
        print('Label Background color before:  ' + lbl_1_bg_color)

        self.lbl_1.setStyleSheet('font-size: 16pt; color: blue; background-color:cyan; font-weight: bold;')
        
        lbl_1_bg_color = self.lbl_1.palette().color(QPalette.Base).name()
        print('Label Background color after:  ' + lbl_1_bg_color)

    # Go to PrefWindow
    #####################################################################
    def ChangeToPrefWindow(self):
        lab_text_1 = self.lbl_1.text()
        lab_bg_color_1 = self.lbl_1.palette().color(QPalette.Base).name()

        # PrefWindow().lbl_2.setText(lab_text_2)
        # PrefWindow().lab_bg_color_2.setStyleSheet(f'font-size: 16pt; color: blue; background-color:{lab_bg_color_2}; font-weight: bold;')

        self.cams = PrefWindow()
        self.cams.show()
        self.close()


class PrefWindow(QWidget):
    def __init__( self ):
        super().__init__()

        self.setGeometry(100, 100, 500, 400)
        self.setWindowTitle("Settings Window")

        self.createPrefWindow()

    def createPrefWindow( self ):

        self.vbox_2 = QVBoxLayout()

        self.lbl_2 = QLabel('Label 2 Init')
        self.lbl_2.move(50, 50)
        self.lbl_2.setStyleSheet('font-size: 13pt; color: blue; background-color:lightgreen; font-weight: bold;')

        self.btnChange_2 = QPushButton("Change Label Text")
        self.btnChange_2.setFixedSize(200, 50)
        self.btnChange_2.clicked.connect(self.chaneLabelText_2)
        self.btnChange_2.setStyleSheet('font-size: 12pt; color: blue; background-color:lightcyan; font-weight: bold;')

        self.btnSave = QPushButton("Save and Quit")
        self.btnSave.setFixedSize(200, 50)
        self.btnSave.setStyleSheet('font-size: 12pt; color: blue; background-color:lightcyan; font-weight: bold;'
            )
        self.btnSave.clicked.connect(self.ChangeToMainWindow)

        self.vbox_2.addWidget(self.lbl_2)
        self.vbox_2.addWidget(self.btnChange_2)
        self.vbox_2.addWidget(self.btnSave)

        self.setLayout(self.vbox_2)


    def chaneLabelText_2(self):
        print('Label Text before: ' + self.lbl_2.text())
        self.lbl_2.setText('Labl 2 is new. \nIts Background color is also new!')
        print('Label Text after:  ' + self.lbl_2.text())

        lbl_2_bg_color = self.lbl_2.palette().color(QPalette.Base).name()
        print('Label Background color before:  ' + lbl_2_bg_color)

        self.lbl_2.setStyleSheet('font-size: 16pt; color: blue; background-color:cyan; font-weight: bold;')
        
        lbl_2_bg_color = self.lbl_2.palette().color(QPalette.Base).name()
        print('Label Background color after:  ' + lbl_2_bg_color)

    # Go to MainWindow
    #####################################################################
    def ChangeToMainWindow( self ):
        lab_text_2 = self.lbl_2.text()
        lab_bg_color_2 = self.lbl_2.palette().color(QPalette.Base).name()

        MainWindow().lbl_1.setText(lab_text_1)
        MainWindow().lab_bg_color_1.setStyleSheet(f'font-size: 16pt; color: blue; background-color:{lab_bg_color_1}; font-weight: bold;')

        self.cams = MainWindow()
        self.cams.show()
        self.close()

def main():
    import sys
    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()

    sys._excepthook = sys.excepthook

    def exception_hook( exctype, value, traceback ):
        print(exctype, value, traceback)
        sys._excepthook(exctype, value, traceback)
        sys.exit(1)

    sys.excepthook = exception_hook

    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

【问题讨论】:

    标签: python pyqt5


    【解决方案1】:

    您不必每次都创建self.cams = MainWindow()

    创建self.cams = PrefWindow(self) 对象时,传递对MainWindow 对象的引用。

    from PyQt5.QtWidgets import *
    from PyQt5.QtGui import *
    
    #lab_text_1 = ''
    #lab_bg_color_1 = ''
    #lab_text_2 = ''
    #lab_bg_color_2 = ''
    
    
    class PrefWindow(QWidget):
        def __init__( self, parent=None ):                                    # + parent
            super().__init__()
            self.parent = parent                                              # + parent
    
            self.setGeometry(100, 100, 500, 400)
            self.setWindowTitle("Settings Window")
            self.createPrefWindow()
            
            self.lab_text_2 = ''                                              # +++
            self.lab_bg_color_2 = ''                                          # +++
    
        def createPrefWindow( self ):
            self.vbox_2 = QVBoxLayout()
    
            self.lbl_2 = QLabel('Label 2 Init')
            self.lbl_2.move(50, 50)
            self.lbl_2.setStyleSheet('font-size: 13pt; color: blue; background-color:lightgreen; font-weight: bold;')
    
            self.btnChange_2 = QPushButton("Change Label Text")
            self.btnChange_2.setFixedSize(200, 50)
            self.btnChange_2.clicked.connect(self.chaneLabelText_2)
            self.btnChange_2.setStyleSheet('font-size: 12pt; color: blue; background-color:lightcyan; font-weight: bold;')
    
            self.btnSave = QPushButton("Save and Quit")
            self.btnSave.setFixedSize(200, 50)
            self.btnSave.setStyleSheet(
                'font-size: 12pt; color: blue; background-color:lightcyan; font-weight: bold;'
            )
            self.btnSave.clicked.connect(self.ChangeToMainWindow)
    
            self.vbox_2.addWidget(self.lbl_2)
            self.vbox_2.addWidget(self.btnChange_2)
            self.vbox_2.addWidget(self.btnSave)
            self.setLayout(self.vbox_2)
    
        def chaneLabelText_2(self):
            print('Label Text before: ' + self.lbl_2.text())
            self.lbl_2.setText('Labl 2 is new. \nIts Background color is also new!')
            print('Label Text after:  ' + self.lbl_2.text())
    
            lbl_2_bg_color = self.lbl_2.palette().color(QPalette.Base).name()
            print('Label Background color before:  ' + lbl_2_bg_color)
    
            self.lbl_2.setStyleSheet('font-size: 16pt; color: blue; background-color:cyan; font-weight: bold;')
            
            lbl_2_bg_color = self.lbl_2.palette().color(QPalette.Base).name()
            print('Label Background color after:  ' + lbl_2_bg_color)
    
        # Go to MainWindow
        #####################################################################
        def ChangeToMainWindow( self ):
            self.lab_text_2 = self.lbl_2.text()
            self.lab_bg_color_2 = self.lbl_2.palette().color(QPalette.Base).name()
    
    ###      MainWindow --> self.parent
    #        MainWindow().lbl_1.setText(lab_text_1)
            self.parent.lbl_1.setText(self.lab_text_2)                       # ? lab_text_2
            self.parent.lbl_1.setStyleSheet(
                f'font-size: 16pt; color: blue; background-color:{self.lab_bg_color_2}; font-weight: bold;')
    
    # -       self.cams = MainWindow()
            self.parent.show()
            self.hide()
            
            
    class MainWindow(QWidget):
        def __init__( self ):
            super().__init__()
            self.setGeometry(100, 100, 500, 400)
            self.setWindowTitle("Saving Window status")
            self.createMainWindow()
    # +
            self.cams = PrefWindow(self)                                   # +++ + self
            self.lab_text_1 = ''                                           # +++
            self.lab_bg_color_1 = ''                                       # +++ 
    
        def createMainWindow( self ):
            self.vbox_1 = QVBoxLayout()
    
            self.lbl_1 = QLabel('Label 1 Init')
            self.lbl_1.move(50, 50)
            self.lbl_1.setStyleSheet('font-size: 13pt; color: blue; background-color:lightgreen; font-weight: bold;')
    
            self.btnChange_1 = QPushButton("Change Label Text")
            self.btnChange_1.setFixedSize(200, 50)
            self.btnChange_1.clicked.connect(self.chaneLabelText_1)
            self.btnChange_1.setStyleSheet('font-size: 12pt; color: blue; background-color:lightcyan; font-weight: bold;')
    
            self.btnSettings = QPushButton("Settings")
            self.btnSettings.setFixedSize(200, 50)
            self.btnSettings.clicked.connect(self.ChangeToPrefWindow)
            self.btnSettings.setStyleSheet('font-size: 12pt; color: blue; background-color:lightcyan; font-weight: bold;')
    
            self.vbox_1.addWidget(self.lbl_1)
            self.vbox_1.addWidget(self.btnChange_1)
            self.vbox_1.addWidget(self.btnSettings)
            self.setLayout(self.vbox_1)
    
        def chaneLabelText_1(self):
            print('Label Text before: ' + self.lbl_1.text())
            self.lbl_1.setText('Labl 1 is new.\nIts Background color is also new!')
            print('Label Text after:  ' + self.lbl_1.text())
    
            lbl_1_bg_color = self.lbl_1.palette().color(QPalette.Base).name()
            print('Label Background color before:  ' + lbl_1_bg_color)
    
            self.lbl_1.setStyleSheet('font-size: 16pt; color: blue; background-color:cyan; font-weight: bold;')
            
            lbl_1_bg_color = self.lbl_1.palette().color(QPalette.Base).name()
            print('Label Background color after:  ' + lbl_1_bg_color)
    
    
        # Go to PrefWindow
        #####################################################################
        def ChangeToPrefWindow(self):
            self.lab_text_1 = self.lbl_1.text()
            self.lab_bg_color_1 = self.lbl_1.palette().color(QPalette.Base).name()
    
            # PrefWindow().lbl_2.setText(lab_text_2)
            # PrefWindow().lab_bg_color_2.setStyleSheet(f'font-size: 16pt; color: blue; background-color:{lab_bg_color_2}; font-weight: bold;')
    
    #        self.cams = PrefWindow()
            self.cams.show()
            self.hide()                                                   # close()
    
    
    def main():
        import sys
        app = QApplication(sys.argv)
        window = MainWindow()
        window.show()
    
        sys._excepthook = sys.excepthook
    
        def exception_hook( exctype, value, traceback ):
            print(exctype, value, traceback)
            sys._excepthook(exctype, value, traceback)
            sys.exit(1)
    
        sys.excepthook = exception_hook
    
        sys.exit(app.exec_())
    
    if __name__ == '__main__':
        main()
    

    下面是我修改后的代码。

    from PyQt5.QtWidgets import *
    from PyQt5.QtGui import *
    
    colors = ['yellow', 'cyan', 'orange', 'white', 'magenta', 'lightgreen', ]
    I = 0
    
    class PrefWindow(QWidget):
        def __init__( self, parent=None ):   # + parent
            super().__init__()
            self.parent = parent             # + parent
    
            self.setGeometry(100, 100, 500, 400)
            self.setWindowTitle("Settings Window")
            self.createPrefWindow()
    
            self.lab_text_2 = ''              # +++
            self.lab_bg_color_2 = ''          # +++
    
        def createPrefWindow( self ):
            self.vbox_2 = QVBoxLayout()
    
            self.lbl_2 = QLabel('Label 2 Init\nOn the Settings Window')
            self.lbl_2.move(50, 50)
            self.lbl_2.setStyleSheet('font-size: 13pt; color: blue; background-color:lightgreen; font-weight: bold;')
    
            self.btnChange_2 = QPushButton("Change Label Text")
            self.btnChange_2.setFixedSize(200, 50)
            self.btnChange_2.clicked.connect(self.chaneLabelText_2)
            self.btnChange_2.setStyleSheet('font-size: 12pt; color: blue; background-color:lightcyan; font-weight: bold;')
    
            self.btnSave = QPushButton("Save and Quit")
            self.btnSave.setFixedSize(200, 50)
            self.btnSave.setStyleSheet('font-size: 12pt; color: blue; background-color:lightcyan; font-weight: bold;')
            self.btnSave.clicked.connect(self.ChangeToMainWindow)
    
            self.vbox_2.addWidget(self.lbl_2)
            self.vbox_2.addWidget(self.btnChange_2)
            self.vbox_2.addWidget(self.btnSave)
            self.setLayout(self.vbox_2)
    
        def chaneLabelText_2( self ):
            global I
    
            print('Label Text before: ' + self.lbl_2.text())
            self.lbl_2.setText(f'I = {I % 6}\nLabl 2 is new. \nIts Background color is also new!\nOn the Settings Window')
            print('Label Text after:  ' + self.lbl_2.text())
    
            lbl_2_bg_color = self.lbl_2.palette().color(QPalette.Base).name()
            print('Label Background color before:  ' + lbl_2_bg_color)
    
            COLOR = colors[I % 6]
            self.lbl_2.setStyleSheet(f'font-size: 16pt; color: blue; background-color:{COLOR}; font-weight: bold;')
            I += 1
    
            lbl_2_bg_color = self.lbl_2.palette().color(QPalette.Base).name()
            print('Label Background color after:  ' + lbl_2_bg_color)
    
        # Go to MainWindow
        #####################################################################
        def ChangeToMainWindow( self ):
            self.lab_text_2 = self.lbl_2.text()
            self.lab_bg_color_2 = self.lbl_2.palette().color(QPalette.Base).name()
    
            # self.parent.lbl_1.setText(self.lab_text_1)
            # self.parent.lbl_1.setStyleSheet(f'font-size: 16pt; color: blue; background-color:{self.lab_bg_color_1}; font-weight: bold;')
    
            self.parent.show()
            self.hide()
    
    class MainWindow(QWidget):
        def __init__( self ):
            super().__init__()
            self.setGeometry(100, 100, 500, 400)
            self.setWindowTitle("Saving Window status")
            self.createMainWindow()
            # +
            self.cams = PrefWindow(self)      # +++ + self
            self.lab_text_1 = ''              # +++
            self.lab_bg_color_1 = ''          # +++
    
        def createMainWindow( self ):
            self.vbox_1 = QVBoxLayout()
    
            self.lbl_1 = QLabel('Label 1 Init\nOn the MainWindow')
            self.lbl_1.move(50, 50)
            self.lbl_1.setStyleSheet('font-size: 13pt; color: blue; background-color:yellow; font-weight: bold;')
    
            self.btnChange_1 = QPushButton("Change Label Text")
            self.btnChange_1.setFixedSize(200, 50)
            self.btnChange_1.clicked.connect(self.chaneLabelText_1)
            self.btnChange_1.setStyleSheet('font-size: 12pt; color: blue; background-color:lightcyan; font-weight: bold;')
    
            self.btnSettings = QPushButton("Settings")
            self.btnSettings.setFixedSize(200, 50)
            self.btnSettings.clicked.connect(self.ChangeToPrefWindow)
            self.btnSettings.setStyleSheet('font-size: 12pt; color: blue; background-color:lightcyan; font-weight: bold;')
    
            self.vbox_1.addWidget(self.lbl_1)
            self.vbox_1.addWidget(self.btnChange_1)
            self.vbox_1.addWidget(self.btnSettings)
            self.setLayout(self.vbox_1)
    
        def chaneLabelText_1( self ):
            print('Label Text before: ' + self.lbl_1.text())
            self.lbl_1.setText('Labl 1 is new.\nIts Background color is also new!\nOn the MainWindow')
            print('Label Text after:  ' + self.lbl_1.text())
    
            lbl_1_bg_color = self.lbl_1.palette().color(QPalette.Base).name()
            print('Label Background color before:  ' + lbl_1_bg_color)
    
            self.lbl_1.setStyleSheet('font-size: 16pt; color: blue; background-color:cyan; font-weight: bold;')
    
            lbl_1_bg_color = self.lbl_1.palette().color(QPalette.Base).name()
            print('Label Background color after:  ' + lbl_1_bg_color)
    
        # Go to PrefWindow
        #####################################################################
        def ChangeToPrefWindow( self ):
            self.lab_text_1 = self.lbl_1.text()
            self.lab_bg_color_1 = self.lbl_1.palette().color(QPalette.Base).name()
    
            # self.parent.lbl_2.setText(self.lab_text_2)
            # PrefWindow().lbl_2.setStyleSheet(f'font-size: 16pt; color: blue; background-color:{PrefWindow().lab_bg_color_2}; font-weight: bold;')
    
            self.cams.show()
            self.hide()  # close()
    
    def main():
        import sys
        app = QApplication(sys.argv)
        window = MainWindow()
        window.show()
    
        sys._excepthook = sys.excepthook
    
        def exception_hook( exctype, value, traceback ):
            print(exctype, value, traceback)
            sys._excepthook(exctype, value, traceback)
            sys.exit(1)
    
        sys.excepthook = exception_hook
    
        sys.exit(app.exec_())
    
    if __name__ == '__main__':
        main()
    

    【讨论】:

    • 我不知道为什么我的帖子被管理员删除了。我发送了您的代码的更正版本作为答案,但三个小时后它被删除了。我不知道我使用了哪个坏规则
    • 我试图理解您修改后的代码,并且也进行了修改以按我的意愿运行。我还在 changeLabelText_2 方法中添加了 6 种颜色,以查看当我返回 PrefWindow 时更改是否真的持久。似乎它以某种方式起作用 事情是它只在一个方向上起作用。我尝试添加与您在 PrefWindow 中所做的相同的方法来放入 MainWindow 以保留标签属性的状态,但没有奏效。
    • 我添加的方法不起作用,因为我认为如果 PrefWindow 之前是 MainWindow 的子类,则不允许使 MainWindow 成为 PrefWindow 的子类。因为在我的实际项目中,我的设置窗口(PrefWindow)上有很多变量要在 MainWindow 上设置和使用,管理所有设置值以保存在 .INI 文件中并每次加载此文件的最佳方法是什么在启动程序时。如果有任何更改,则应通过按 Save&Quit 按钮将它们带到 MainWindow,如果按下 Quit 按钮则忽略它们。
    • 我把修改后的代码再放到问题区。如果你能解释一下小部件、父母和孩子之间的关系吗?我在下面添加修改后的代码。非常感谢,提前。问候莫森
    猜你喜欢
    • 2015-06-03
    • 1970-01-01
    • 2020-12-02
    • 1970-01-01
    • 1970-01-01
    • 2018-04-13
    • 2016-04-14
    • 2021-02-13
    • 2014-01-26
    相关资源
    最近更新 更多