值更改时更改颜色组合框
Posted
技术标签:
【中文标题】值更改时更改颜色组合框【英文标题】:Change color ComboBox when value change 【发布时间】:2021-02-09 12:18:51 【问题描述】:我在 Pyqt5 中有一个带有 Combobox 的表格。我的 Combobox 有 2 个值:True 或 False,我想将 Combobox 的颜色更改为 2 种不同的颜色:当值为 True -> Green 时,当值为 False -> Red 时。我尝试使用样式表更改颜色,但它只能将整个组合框更改为红色或绿色,如下所示:
如何根据它们的值更改 2 种不同颜色的组合框?
我的代码如下:
# -*- coding: utf-8 -*-
"""
Created on Tue Oct 27 09:21:24 2020
@author: actnmk
"""
import sys
from PyQt5.QtWidgets import (QWidget, QLabel, QLineEdit, QTextEdit, QGridLayout, QApplication)
import pandas as pd
import numpy as np
import PyQt5
from PyQt5.QtWidgets import QVBoxLayout, QPushButton, QGroupBox, QHBoxLayout, QMainWindow, QApplication, QLineEdit, QFileDialog, QTableWidget,QTableWidgetItem, QTableView, QStyledItemDelegate
from PyQt5 import QtCore, QtGui, QtWidgets
import os
from PyQt5.QtWidgets import (QWidget, QPushButton, QHBoxLayout, QVBoxLayout, QApplication)
from PyQt5.QtGui import QIcon
import re
def dataframe():
lst = [['tom', 'reacher', 'True'], ['krish', 'pete', 'True'],
['nick', 'wilson', 'True'], ['juli', 'williams', 'True']]
df = pd.DataFrame(lst, columns =['FName', 'LName', 'Student?'], dtype = float)
return df
class Delegate(QtWidgets.QItemDelegate):
def __init__(self, owner, choices):
super().__init__(owner)
self.items = choices
def createEditor(self, parent, option, index):
self.editor = QtWidgets.QComboBox(parent)
self.editor.currentIndexChanged.connect(self.commit_editor)
self.editor.addItems(self.items)
return self.editor
def paint(self, painter, option, index):
value = index.data(QtCore.Qt.DisplayRole)
style = QtWidgets.QApplication.style()
opt = QtWidgets.QStyleOptionComboBox()
opt.text = str(value)
opt.rect = option.rect
style.drawComplexControl(QtWidgets.QStyle.CC_ComboBox, opt, painter)
QtWidgets.QItemDelegate.paint(self, painter, option, index)
def commit_editor(self): ####test
editor = self.sender()
self.commitData.emit(editor)
def setEditorData(self, editor, index):
value = index.data(QtCore.Qt.DisplayRole)
num = self.items.index(value)
editor.setCurrentIndex(num)
def setModelData(self, editor, model, index):
value = editor.currentText()
model.setData(index, value, QtCore.Qt.EditRole)
def updateEditorGeometry(self, editor, option, index):
editor.setGeometry(option.rect)
class PandasModel(QtCore.QAbstractTableModel):
def __init__(self, data, parent=None):
QtCore.QAbstractTableModel.__init__(self, parent)
self._data = data
def rowCount(self, parent=None):
return self._data.shape[0]
def columnCount(self, parent=None):
return self._data.shape[2]
def flags(self, index):
return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
def data(self, index, role=QtCore.Qt.DisplayRole):
if index.isValid():
if role == QtCore.Qt.DisplayRole:
return str(self._data.iloc[index.row(), index.column()])
return None
def headerData(self, col, orientation, role):
if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
return self._data.columns[col]
return None
def setData(self, index, value, role=QtCore.Qt.EditRole):
self._data.iloc[index.row(), index.column()] = value
return True
class MyWindow(QWidget):
def __init__(self):
super().__init__()
self.setGeometry(300, 200 ,600, 400)
self.setWindowTitle('Test')
self.initUI()
def show_data(self):
choices = ['True', 'False']
self.model = PandasModel(dataframe())
self.table_data.setModel(self.model)
self.table_data.setItemDelegateForColumn(2, Delegate(self,choices))
##make combo boxes editable with a single-click:
for row in range(5):
self.table_data.openPersistentEditor(self.model.index(row, 2))
def print_data(self):
print(self.table_data.model()._data)
def initUI(self):
welcom = QLabel('Welcome to my app!')
self.btn_print_data = QPushButton('print data')
self.btn_print_data.clicked.connect(self.print_data) ##test
self.btn_show_table = QPushButton('show data')
self.btn_show_table.clicked.connect(self.show_data)
self.table_data = QTableView()
#self.table_result = QTableView()
hbox1 = QHBoxLayout()
hbox1.addWidget(welcom)
vbox2 = QVBoxLayout()
vbox2.addWidget(self.btn_show_table)
vbox2.addWidget(self.btn_print_data) ####test
vbox3 = QVBoxLayout()
vbox3.addWidget(self.table_data)
#vbox3.addWidget(self.table_result)
hbox2 = QHBoxLayout()
hbox2.addLayout(vbox2)
hbox2.addLayout(vbox3)
vbox1 = QVBoxLayout()
vbox1.addLayout(hbox1)
vbox1.addLayout(hbox2)
self.setLayout(vbox1)
self.show()
style = '''
QComboBox
background-color : lightgreen;
'''
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setStyleSheet(style)
ex = MyWindow()
sys.exit(app.exec_())
【问题讨论】:
【参考方案1】:注意:代码有错误,必须改成:
def columnCount(self, parent=None):
return self._data.shape[1]
另一方面,解决方案是根据选择更改每个组合框的 Qt StyleSheet:
def commit_editor(self):
editor = self.sender()
color = QtGui.QColor()
if editor.currentText() == "True":
color = QtGui.QColor("lightgreen")
elif editor.currentText() == "False":
color = QtGui.QColor("red")
qss = """QComboBoxbackground-color : %s;""" % (color.name(),)
editor.setStyleSheet(qss)
self.commitData.emit(editor)
【讨论】:
以上是关于值更改时更改颜色组合框的主要内容,如果未能解决你的问题,请参考以下文章
有没有办法更改 Microsoft Access 中下拉列表的组合框按钮的颜色