#python #pyqt #pyqt5 #qcombobox #qtstylesheets
#python #pyqt #pyqt5 #qcombobox #qtstylesheets
Вопрос:
У меня есть таблица в Pyqt5 со списком. В моем выпадающем списке есть 2 значения: True или False, я хочу изменить цвет выпадающего списка на 2 разных цвета: при значении True -> Зеленый, при значении False -> Красный. Я попытался изменить цвет с помощью таблицы стилей, но он может изменить только весь выпадающий список на красный или зеленый, как показано ниже:
как я могу изменить выпадающий список на 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 каждого выпадающего списка в зависимости от выбора:
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 = """QComboBox{background-color : %s;}""" % (color.name(),)
editor.setStyleSheet(qss)
self.commitData.emit(editor)