python - pyqt5更改按钮随机随机崩溃
问题描述
我想使用递归来改变推送背景。但是 Gui 会随机崩溃。我收到以下消息。“无法解析对象 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()
主文件
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,代码将正确执行。在我看来,线程有一些问题。但我不确定。我希望有人可以帮助我解决它。谢谢你。
解决方案
绝不应该从另一个线程访问或修改Qt 小部件。
我相信QTimer足以满足您的需要,但我无法对其进行测试,因为您没有提供完全最小的、可重现的示例。
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()
正如我在另一个问题中已经告诉您的那样,我强烈建议您不要使用样式表进行样式比较。
推荐阅读
- flutter - 在 Yocto 上颤抖?
- apache-spark - 加入 Spark 返回重复的隐式数据类型不匹配
- postgresql - 基于同一张表刷新多个物化视图的触发器
- firebase - 可以像这样将 Auth0 集成到 Firebase 吗?
- python - 如何将具有键值对的列表转换为字典
- multithreading - 为什么这段代码会生成重复的 id?
- arrays - 用不同形状的数组制作一个数组
- python - 安装 GDAL 以与 Python 一起使用的持续问题(Mac 用户)
- c# - 如何将 C# WinForm 应用程序和安装程序移植到 MacOS?
- java - 为不支持的浏览器显示 JSP