python - PyQt5 - 如何更改列表小部件中的特定项目背景颜色
问题描述
这个程序有一个简单的列表小部件。如何在不单击列表中更改任何特定项目的背景颜色?
from PyQt5 import QtWidgets, uic, QtGui
import threading
app = QtWidgets.QApplication([])
ui = uic.loadUi("app.ui")
update_ui = True
ui.lst_positions.addItem("Item 1")
ui.lst_positions.addItem("Item 2")
ui.lst_positions.addItem("Item 3")
def ui_update():
while update_ui == True:
# Updating labels works fine with threading
ui.lbl_in_position.setText("Random text")
# This does not work with threading
item = ui.lst_positions.item(1)
item.setBackground(QtGui.QColor("red"))
ui_thread = threading.Thread(target=ui_update)
ui_thread.daemon = True
ui_thread.start()
ui.show()
app.exec()
解决方案
任务很简单:
- 获取与索引关联的 QListWidgetItem。
- 使用 QListWidgetItem 的 setBackground 方法。
item = ui.lst_positions.item(item_number_to_change)
item.setBackground(QtGui.QColor("red"))
更新:
问题是您不应该从另一个线程更新 GUI,因为 GUI 的元素不是线程安全的,因此您会收到您在评论中指出的警告。一种解决方案是创建一个具有信号(线程安全)的 QObject,以在线程之间交换信息。
# ...
class Signaller(QtCore.QObject):
textChanged = QtCore.pyqtSignal(str)
itemChanged = QtCore.pyqtSignal(int, QtGui.QColor)
def ui_update(qobject):
while update_ui == True:
qobject.textChanged.emit("Random text")
qobject.itemChanged.emit(i, QtGui.QColor("red"))
def foo(i, color):
item = ui.lst_positions.item(i)
if item:
item.setBackground(color)
signaller = Signaller()
signaller.textChanged.connect(ui.lbl_in_position.setText)
signaller.itemChanged.connect(foo)
ui_thread = threading.Thread(target=ui_update, args=(signaller,))
ui_thread.daemon = True
ui_thread.start()
# ...
注意:仅仅因为文本显示正确并不意味着它是正确的。如果直接从另一个线程更新 GUI,Qt 不保证(这意味着它可能会失败)正确的操作。
推荐阅读
- javascript - 在闪亮中重新执行js回调
- javascript - 如何创建模态弹出框 - Google Chrome 扩展
- python - 使用 Python 创建 XML 文件
- ssas - SQL Server Analysis Services 表格模型的压力测试
- orbeon - Orbeon Forms - 引用模板部分之外的控件值
- javascript - MERN 堆栈密码重置在前端不起作用(邮递员工作得很好)
- php - 使用电子邮件通道时,如何使用通知程序将通知作为 HTML 内容发送?
- arrays - 当json值包含空格时将jq输出分配给bash数组
- angular - Primeng p-toast 显示在内部 div
- php - meta_query 过滤器:获取三个条件中的两个匹配的帖子