PyQt5:根据选择的元素与数据框中的另一个元素匹配设置自定义组合框文本的字体颜色

Posted

技术标签:

【中文标题】PyQt5:根据选择的元素与数据框中的另一个元素匹配设置自定义组合框文本的字体颜色【英文标题】:PyQt5: Set font color of custom ComboBox text depending on element selected matching another element in a dataframe 【发布时间】:2019-03-17 11:45:15 【问题描述】:

我有以下代码:

import sys
from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QSize, Qt, QSortFilterProxyModel, QStringListModel
from PyQt5.QtGui import QIcon, QFont


class ExtendedComboBox(QComboBox):
    def __init__(self, parent=None):
        super(ExtendedComboBox, self).__init__(parent)

        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)

        # add a filter model to filter matching items
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.pFilterModel.setSourceModel(self.model())

        # add a completer, which uses the filter model
        self.completer = QCompleter(self.pFilterModel, self)
        # always show all (filtered) completions
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.setCompleter(self.completer)

        # connect signals
        self.lineEdit().textEdited.connect(self.pFilterModel.setFilterFixedString)
        self.completer.activated.connect(self.on_completer_activated)


    # on selection of an item from the completer, select the corresponding item from combobox
    def on_completer_activated(self, text):
        if text:
            index = self.findText(text)
            self.setCurrentIndex(index)
            self.activated[str].emit(self.itemText(index))


    # on model change, update the models of the filter and completer as well
    def setModel(self, model):
        super(ExtendedComboBox, self).setModel(model)
        self.pFilterModel.setSourceModel(model)
        self.completer.setModel(self.pFilterModel)


    # on model column change, update the model column of the filter and completer as well
    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(ExtendedComboBox, self).setModelColumn(column)

class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()

        self.setGeometry(100, 100, 800, 600)
        self.centerOnScreen()
        self.combo = ExtendedComboBox(self)
        self.my_list = ['','Option 1', 'Option 2', 'Option 3','Option 4', 'Option 5']
        self.combo.addItems(self.my_list)

        self.combo.setFixedWidth(250)

    def centerOnScreen (self):
        resolution = QDesktopWidget().screenGeometry()
        self.move((resolution.width() / 2) - (self.frameSize().width() / 2),
                  (resolution.height() / 2) - (self.frameSize().height() / 2))

if __name__ == '__main__':

    app = QApplication(sys.argv)
    mainWin = MainWindow()
    mainWin.show()
    sys.exit(app.exec_())

它使用我在 *** 上找到的代码创建一个带有自动完成功能的自定义 ComboBox。当前 Combobox 的选择由['','Option 1', 'Option 2', 'Option 3','Option 4', 'Option 5']列表组成

但是我想知道当 Combobox 元素更新时,是否有办法根据与数据框中元素的匹配来更改 Combobox 的字体颜色。

例如,如果我有以下数据框:

    Option number    Color
0    Option 2         Red
1    Option 3         Blue
2    Option 5         Gray

我希望 Combobox 中的字体颜色更改为当 Combobox 中选择的元素与数据框中的相应元素匹配时指示的颜色,并在不匹配时使用默认字体颜色。

有什么方法可以在 PyQt5 中实现吗?

【问题讨论】:

见***.com/questions/50711763/… 谢谢。它帮助我想出了一个可行的例子。 【参考方案1】:

在@S 建议的线程的帮助下,这是代码的工作示例。尼克:

import sys
from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QSize, Qt, QSortFilterProxyModel, QStringListModel
from PyQt5.QtGui import QIcon, QFont
import pandas as pd
from pandas import DataFrame

class ExtendedComboBox(QComboBox):
    def __init__(self, parent=None):
        super(ExtendedComboBox, self).__init__(parent)

        self.setFocusPolicy(Qt.StrongFocus)
        self.setEditable(True)

        # add a filter model to filter matching items
        self.pFilterModel = QSortFilterProxyModel(self)
        self.pFilterModel.setFilterCaseSensitivity(Qt.CaseInsensitive)
        self.pFilterModel.setSourceModel(self.model())

        # add a completer, which uses the filter model
        self.completer = QCompleter(self.pFilterModel, self)
        # always show all (filtered) completions
        self.completer.setCompletionMode(QCompleter.UnfilteredPopupCompletion)
        self.setCompleter(self.completer)

        # connect signals
        self.lineEdit().textEdited.connect(self.pFilterModel.setFilterFixedString)
        self.completer.activated.connect(self.on_completer_activated)


    # on selection of an item from the completer, select the corresponding item from combobox
    def on_completer_activated(self, text):
        if text:
            index = self.findText(text)
            self.setCurrentIndex(index)
            self.activated[str].emit(self.itemText(index))


    # on model change, update the models of the filter and completer as well
    def setModel(self, model):
        super(ExtendedComboBox, self).setModel(model)
        self.pFilterModel.setSourceModel(model)
        self.completer.setModel(self.pFilterModel)


    # on model column change, update the model column of the filter and completer as well
    def setModelColumn(self, column):
        self.completer.setCompletionColumn(column)
        self.pFilterModel.setFilterKeyColumn(column)
        super(ExtendedComboBox, self).setModelColumn(column)

class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()

        self.setGeometry(100, 100, 800, 600)
        self.centerOnScreen()
        self.combo = ExtendedComboBox(self)
        self.my_list = ['','Option 1', 'Option 2', 'Option 3','Option 4', 'Option 5']
        self.combo.addItems(self.my_list)
        Data = 'Option Number': ['Option 2','Option 3','Option 5'],'Color': ['red','blue','grey']
        df = DataFrame(Data,columns= ['Option Number', 'Color'])

        self.combo.setFixedWidth(250)

        print(df)

        def combo_changed():
            for color in ('red', 'blue', 'grey'):
                try:
                    if color == df.loc[df['Option Number'].str.contains(self.combo.currentText()), 'Color'].iloc[0]:
                        self.combo.setStyleSheet("QComboBox:editable color:  ".format(color))
                except IndexError:
                    self.combo.setStyleSheet("QComboBox:editable color:  ".format('black'))

        self.combo.currentIndexChanged.connect(combo_changed)

    def centerOnScreen (self):
        resolution = QDesktopWidget().screenGeometry()
        self.move((resolution.width() / 2) - (self.frameSize().width() / 2),
                  (resolution.height() / 2) - (self.frameSize().height() / 2))

if __name__ == '__main__':

    app = QApplication(sys.argv)
    mainWin = MainWindow()
    mainWin.show()
    sys.exit(app.exec_())

【讨论】:

以上是关于PyQt5:根据选择的元素与数据框中的另一个元素匹配设置自定义组合框文本的字体颜色的主要内容,如果未能解决你的问题,请参考以下文章

如何将组合框中的选定元素保存为 PyQt5 中的变量?

Selenium 根据元素的ID属性选择元素

在数据框中动态添加列,列名作为 List 中的元素

从 PyQt5 中的另一个类访问变量

假设某个元素与 R 中的 CSV 文件的文件名相同,则将数据框中的某个元素相乘

如何使小部件随 PyQt5 中的窗口缩放?