4

To set the background-color is fine, but my interface has a Qwidget that changes its background-color at certain point. That will cause the program to crash, and the crash stops when I comment out the color changing code.

This code below will certainly crash ,after running a little while.

import sys
from PySide2.QtWidgets import QWidget,QPushButton,QApplication,QListWidget,QGridLayout,\
QLabel,QMainWindow,QLineEdit,QScrollArea,QVBoxLayout,QMessageBox
from PySide2.QtCore import QTimer,QDateTime,QSize,Qt
from PySide2.QtGui import *
import requests,json
import configparser #
import os
import time
import threading #
from pynput import keyboard #
import requests,json
from math import * 
from functools import partial

class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.resize(320,100)    
        self.setWindowTitle('aaaa')
        self.setStyleSheet("QMainWindow\
        {\
            background-color:white;\
            color:white;\
            margin:0px\
        }")
        self.InitializeWindow()
        self.i=0

    def InitializeWindow(self):
        self.statebar=QWidget(self)
        self.statebar.setGeometry(0, 40, 320, 54)
        print(sys._getframe().f_lineno)
        self.statebar.setStyleSheet("QWidget{background-color:#1EC5CD}")
        self.th_countdown=threading.Thread(target=self.countdown,args=())
        self.th_countdown.setDaemon(True)
        self.th_countdown.start()

        self.message_main=QLabel(self.statebar)
        self.message_main.setGeometry(150,7,40,37)
        self.message_main.setStyleSheet("background:transparent;color:white;margin:0px;font-size:45px;font-weight:bold")
        self.message_main.setWordWrap(True)
        self.message_main.hide()
        self.message_main.setAlignment(Qt.AlignTop|Qt.AlignLeft)
        self.message_signature=QLabel(self.statebar)
        self.message_signature.setGeometry(50,6,42,42)
        self.message_signature.setScaledContents(True)
        self.message_signature.setStyleSheet("background:transparent")

        self.message_result=QLabel(self.statebar)
        self.message_result.setGeometry(150,6,160,25)
        self.message_result.setStyleSheet("background:transparent;color:white;margin:0px;font-size:24px;font-weight:bold")
        self.message_result.setWordWrap(True)
        self.message_result.hide()
        self.message_detail=QLabel(self.statebar)
        self.message_detail.setGeometry(150,34,160,15)
        self.message_detail.setStyleSheet("background:transparent;color:white;margin:0px;font-size:14px")
        self.message_detail.setWordWrap(True)
        self.message_detail.hide()

    def bind(self, ret):
        self.message_result.show()
        self.message_detail.show()
        self.message_main.hide()
        if(ret%2==0):
            self.statebar.setStyleSheet("QWidget{background-color:#1EC5CD}") ##FA6400
            self.message_result.setText(str(ret))
            self.message_detail.setText(str(ret))
        else:
            self.statebar.setStyleSheet("QWidget{background-color:#FA6400}") ##FA6400
            self.message_result.setText(str(ret))
            self.message_detail.setText(str(ret))

    def countdown(self):
        while(1):
            time.sleep(0.2)
            self.i=self.i+1
            self.bind(self.i)

if __name__ == '__main__':
    app = 0
    app = QApplication(sys.argv)
    win = MainWindow()
    #icon = QIcon()
    #icon.addPixmap(QPixmap("./res/mdm.ico"),QIcon.Normal, QIcon.Off)
    #win.setWindowIcon(icon)
    win.show()

    sys.exit(app.exec_())
    pass

sometimes python throw out a error message "Could not parse stylesheet of object...", sometimes it just crash with no message.

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Dery
  • 177
  • 1
  • 11

1 Answers1

5

The countdown method is running on a thread other than the GUI where you are modifying the GUI, and that action is not secure since 2 threads cannot access the same resource causing the problem you are pointing out. The solution is not to modify the GUI directly from another thread but through signals that are thread-safe:

import sys
import time
import threading

from PySide2.QtCore import Qt, Signal, Slot
from PySide2.QtWidgets import QApplication, QLabel, QMainWindow, QWidget


class MainWindow(QMainWindow):
    valueChanged = Signal(int)

    def __init__(self):
        super(MainWindow, self).__init__()
        self.resize(320, 100)
        self.setWindowTitle("aaaa")
        self.setStyleSheet(
            """
            QMainWindow
            {
                background-color:white;
                color:white;
                margin:0px
            }
            """
        )
        self.InitializeWindow()
        self.i = 0

        self.valueChanged.connect(self.bind)

    def InitializeWindow(self):
        self.statebar = QWidget(self)
        self.statebar.setGeometry(0, 40, 320, 54)
        print(sys._getframe().f_lineno)
        self.statebar.setStyleSheet("QWidget{background-color:#1EC5CD}")
        self.th_countdown = threading.Thread(target=self.countdown)
        self.th_countdown.setDaemon(True)
        self.th_countdown.start()

        self.message_main = QLabel(self.statebar)
        self.message_main.setGeometry(150, 7, 40, 37)
        self.message_main.setStyleSheet(
            "background:transparent;color:white;margin:0px;font-size:45px;font-weight:bold"
        )
        self.message_main.setWordWrap(True)
        self.message_main.hide()
        self.message_main.setAlignment(Qt.AlignTop | Qt.AlignLeft)
        self.message_signature = QLabel(self.statebar)
        self.message_signature.setGeometry(50, 6, 42, 42)
        self.message_signature.setScaledContents(True)
        self.message_signature.setStyleSheet("background:transparent")

        self.message_result = QLabel(self.statebar)
        self.message_result.setGeometry(150, 6, 160, 25)
        self.message_result.setStyleSheet(
            "background:transparent;color:white;margin:0px;font-size:24px;font-weight:bold"
        )
        self.message_result.setWordWrap(True)
        self.message_result.hide()
        self.message_detail = QLabel(self.statebar)
        self.message_detail.setGeometry(150, 34, 160, 15)
        self.message_detail.setStyleSheet(
            "background:transparent;color:white;margin:0px;font-size:14px"
        )
        self.message_detail.setWordWrap(True)
        self.message_detail.hide()

    @Slot(int)
    def bind(self, ret):
        self.message_result.show()
        self.message_detail.show()
        self.message_main.hide()
        qss = "QWidget{background-color:%s}" % (
            "#1EC5CD" if ret % 2 == 0 else "#FA6400"
        )
        self.statebar.setStyleSheet(qss)
        self.message_result.setNum(ret)
        self.message_detail.setNum(ret)

    def countdown(self):
        while True:
            time.sleep(0.2)
            self.i += 1
            self.valueChanged.emit(self.i)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = MainWindow()
    win.show()
    sys.exit(app.exec_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241