我想使用递归更改推送背景。但是桂会随机崩溃。我收到以下消息。 “无法解析对象QPushButton(0x2b04523d9e0)的样式表” 以下是我的代码。包括2个文件,一个用于Gui,另一个用于Main。
gui_01.py
import ctypes
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
user32 = ctypes.windll.user32
self.screensize_width = user32.GetSystemMetrics(0)
self.screensize_height = user32.GetSystemMetrics(1)
self.rows = (self.screensize_height - 100) // 20
self.columns = (self.screensize_width - 100) // 20
MainWindow.setObjectName("MainWindow")
MainWindow.setGeometry(0, 0, self.screensize_width, self.screensize_height)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 20))
self.menubar.setObjectName("menubar")
self.menuFile = QtWidgets.QMenu(self.menubar)
self.menuFile.setObjectName("menuFile")
self.menuAuthor = QtWidgets.QMenu(self.menubar)
self.menuAuthor.setObjectName("menuAuthor")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
#self.statusbar.setGeometry(QtCore.QRect(0, self.rows*20, 400, 20))
self.statusbar.setToolTip("")
self.statusbar.setWhatsThis("")
self.statusbar.setAccessibleName("")
self.statusbar.setAccessibleDescription("")
self.statusbar.setAutoFillBackground(True)
self.statusbar.setObjectName("statusbar")
self.statusbar.setStyleSheet("background-color: red;")
MainWindow.setStatusBar(self.statusbar)
self.actionOpen = QtWidgets.QAction(MainWindow)
self.actionOpen.setObjectName("actionOpen")
self.actionSave_as = QtWidgets.QAction(MainWindow)
self.actionSave_as.setObjectName("actionSave_as")
self.actionLife_game = QtWidgets.QAction(MainWindow)
self.actionLife_game.setObjectName("actionLife_game")
self.actionAbout_Author = QtWidgets.QAction(MainWindow)
self.actionAbout_Author.setObjectName("actionAbout_Author")
self.menuFile.addAction(self.actionOpen)
self.menuFile.addAction(self.actionSave_as)
self.menuAuthor.addAction(self.actionLife_game)
self.menuAuthor.addSeparator()
self.menuAuthor.addAction(self.actionAbout_Author)
self.menubar.addAction(self.menuFile.menuAction())
self.menubar.addAction(self.menuAuthor.menuAction())
self.start_button = QtWidgets.QPushButton(self.centralwidget)
self.start_button.setGeometry(QtCore.QRect(self.screensize_width - 100, (self.rows-5)*20-1, 50, 51))
self.start_button.setText("Start")
self.start_button.setStyleSheet("QPushButton{background-color: lightGray;border-width: 4px;border-color: black;font-size: 20px;font-weight:bold; font-family: Roman times;}")
self.stop_button = QtWidgets.QPushButton(self.centralwidget)
self.stop_button.setGeometry(QtCore.QRect(self.screensize_width - 50, (self.rows-5)*20-1, 50, 51))
self.stop_button.setText("Stop")
self.stop_button.setStyleSheet("QPushButton{background-color: lightGray;border-width: 4px;border-color: red;font-size: 20px;font-weight:bold; font-family: Roman times;}")
self.clear_button = QtWidgets.QPushButton(self.centralwidget)
self.clear_button.setGeometry(QtCore.QRect(self.screensize_width - 100, (self.rows-5)*20+50, 101, 51))
self.clear_button.setText("Clear")
self.clear_button.setStyleSheet("QPushButton{background-color: lightGray;border-width: 0px;border-color: black;font-size: 20px;font-weight:bold; font-family: Roman times;}")
self.buttons = [[QtWidgets.QPushButton(self.centralwidget) for j in range(self.columns)] for i in
range(self.rows)]
for i in range(self.rows):
for j in range(self.columns):
self.buttons[i][j].setGeometry(QtCore.QRect(j * 20, i * 20, 21, 21))
self.buttons[i][j].setText("")
if (i+j)%2 == 0:
self.buttons[i][j].setStyleSheet("QPushButton{background-color: blue;border-style: solid;border-width: 1px;border-color: black;}")
else:
self.buttons[i][j].setStyleSheet("QPushButton{background-color: white;border-style: solid;border-width: 1px;border-color: black;}")
MainWindow.setCentralWidget(self.centralwidget)
#self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
MainWindow.showMaximized()
main.py
from PyQt5 import QtWidgets, QtGui, QtCore
from PyQt5.QtGui import QPalette, QBrush
from gui_01 import Ui_MainWindow
import sys
import time
import threading
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.live_list = []
self.start_enable = False
self.stop_enable = False
self.stop_have = False
self.red = 0
self.ui.start_button.clicked.connect(self.start_thread)
self.ui.stop_button.clicked.connect(self.stop)
self.ui.clear_button.clicked.connect(self.clear)
for i in range(self.ui.rows):
for j in range(self.ui.columns):
self.ui.buttons[i][j].clicked.connect(lambda state, i=i, j=j: self.action(i, j))
if (i+j)%2 == 0:
self.live_list.append((i, j))
def start_thread(self):
if not self.start_enable:
th1 = threading.Thread(target=self.start, args=())
th1.setDaemon(True)
th1.start()
else:
pass
def start(self):
if not self.stop_enable:
print("Start")
self.start_enable = True
self.stop_have = False
if len(self.live_list) != 0:
if self.red == 0:
for i in range(len(self.live_list)):
self.ui.buttons[self.live_list[i][0]][self.live_list[i][1]].setStyleSheet("QPushButton{background-color: red;border-style: solid;border-width: 1px;border-color: black;}")
self.red = 1
else:
for i in range(len(self.live_list)):
self.ui.buttons[self.live_list[i][0]][self.live_list[i][1]].setStyleSheet("QPushButton{background-color: green;border-style: solid;border-width: 1px;border-color: black;}")
self.red = 0
time.sleep(0.1)
if len(self.live_list) == 0:
self.stop_enable = True
self.start()
else:
print("--------------------------end--------------------------------------")
self.stop_enable = False
self.start_enable = False
def stop(self):
if not self.stop_have:
self.stop_enable = True
self.stop_have = True
else:
pass
def clear(self):
for i in range(len(self.live_list)):
self.ui.buttons[self.live_list[i][0]][self.live_list[i][1]].setStyleSheet("QPushButton{background-color: white;border-style: solid;border-width: 1px;border-color: black;}")
self.live_list = []
def action(self, i, j):
if self.ui.buttons[i][j].styleSheet() == "QPushButton{background-color: white;border-style: solid;border-width: 1px;border-color: black;}":
self.ui.buttons[i][j].setStyleSheet("QPushButton{background-color: blue;border-style: solid;border-width: 1px;border-color: black;}")
self.live_list.append((i, j))
else:
self.ui.buttons[i][j].setStyleSheet("QPushButton{background-color: white;border-style: solid;border-width: 1px;border-color: black;}")
try:
self.live_list.remove((i, j))
except:
pass
# display main window
if __name__ == '__main__':
app = QtWidgets.QApplication([])
window = MainWindow()
window.show()
sys.exit(app.exec_())
我不知道为什么代码会崩溃。如果我用tkinter替换pyqt5,代码将正确执行。在我看来,线程有一些问题。但我不确定。我希望有人可以帮助我解决它。谢谢。
答案 0 :(得分:0)
绝对不要从另一个线程访问或修改Qt小部件。
我相信QTimer可以满足您的需求,但是由于您没有提供完整的minimal, reproducible example,因此我无法对其进行测试。
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
# ...
self.timer = QtCore.QTimer()
self.timer.setInterval(100)
self.timer.timeout.connect(self.updateButtons)
self.ui.start_button.clicked.connect(self.timer.start)
self.ui.stop_button.clicked.connect(self.timer.stop)
self.ui.clear_button.clicked.connect(self.clear)
def updateButtons(self):
if len(self.live_list):
if self.red == 0:
for i in range(len(self.live_list)):
self.ui.buttons[self.live_list[i][0]][self.live_list[i][1]].setStyleSheet("QPushButton{background-color: red;border-style: solid;border-width: 1px;border-color: black;}")
self.red = 1
else:
for i in range(len(self.live_list)):
self.ui.buttons[self.live_list[i][0]][self.live_list[i][1]].setStyleSheet("QPushButton{background-color: green;border-style: solid;border-width: 1px;border-color: black;}")
self.red = 0
else:
self.timer.stop()
正如我在另一个问题中已经告诉您的那样,强烈建议您不要使用样式表进行样式比较。