Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

set color(green/red) in conditions bool in listview



  • import sys
    from PyQt5.QtWidgets import QApplication, QListWidgetItem, QListWidget, QLineEdit, QVBoxLayout, QWidget, QMainWindow, QListView
    from PyQt5.QtCore import Qt, QSortFilterProxyModel
    from PyQt5.QtGui import QIcon, QStandardItemModel, QStandardItem
    import pandas as pd
    
    class MainWindow(QWidget):
        
        def __init__(self):
            super().__init__()            
    
            self.setWindowTitle("Foxy Quizz")
            self.resize(480, 600)
            self.setWindowIcon(QIcon(r"C:\Users\rodri\Projeto\Aulas\logo.ico"))
            pf = pd.read_excel(r'C:\Users\rodri\Projeto\Aulas\Perguntas.xlsx')
    
            mainLayout = QVBoxLayout()
            model = QStandardItemModel(len(pf['Perguntas']), 1)
            model.setHorizontalHeaderLabels(['Perguntas'])
    
            filter_proxy_model = QSortFilterProxyModel()
            filter_proxy_model.setSourceModel(model)
            filter_proxy_model.setFilterCaseSensitivity(Qt.CaseInsensitive)
            filter_proxy_model.setFilterKeyColumn(0)
    
            search_filed = QLineEdit()
            search_filed.setStyleSheet('font-size: 16px; height: 30px;', )  # Estilo/Escala da caixa de pesquisa
            search_filed.textChanged.connect(filter_proxy_model.setFilterRegExp)
            mainLayout.addWidget(search_filed)
            
            lista = QListView()
            lista.setModel(filter_proxy_model)
            
            #for color, cond in zip(pf['Perguntas'], pf['Respostas']):
            for color, cond in zip(pf['Perguntas'], pf['Respostas']):    
             
                item = QStandardItem(color)        
                if cond:
                    item.setForeground(Qt.green)
    
                else:
                    item.setForeground(Qt.red)
                model.setItem(0, item)        
    
            mainLayout.addWidget(lista)
            self.setLayout(mainLayout)
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
    
        demo = MainWindow()
        demo.show()
    
        sys.exit(app.exec_())
            
    

    I'm using QListView, with a folder in excel with 2 columns one with questions and one with answers, I wanted to set the questions in the ListView widget, with the colors green and red, and when I type in the search box identify if the question is whether it is true or not.

    like this https://imgur.com/ueQtEmx.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    @rodrigoml said in set color(green/red) in conditions bool in listview:

    and when I type in the search box identify if the question is whether it is true or not.

    This part is not really clear, can you maybe rephrase it ?



  • @SGaist

    class FoxyQuizz(QtWidgets.QWidget):
        def __init__(self):
            super().__init__()
            self.setWindowTitle("Foxy Quizz")
            self.resize(480, 600)   # Tamanho do applicativo
            self.setWindowIcon(QtGui.QIcon(r"C:\Users\rodri\Projeto\Aulas\logo.ico"))
            mainLayout = QtWidgets.QVBoxLayout()
    
            pt = pd.read_excel(r'C:\Users\rodri\Projeto\Aulas\Perguntas.xlsx')
                    
            
            model = QtGui.QStandardItemModel(len(pt['Perguntas']), 1)    # id das perguntas
            #model.setHorizontalHeaderLabels(['Perguntas'])  # Texto Topo da tela
          
    
            for row, pergunta in enumerate(pt['Perguntas']):
                item = QtGui.QStandardItem(pergunta)
                model.setItem(row, 0, item)
    
    
            # Filtrando a caixa de pesquisa
            filter_proxy_model = QtCore.QSortFilterProxyModel()
            filter_proxy_model.setSourceModel(model)
            filter_proxy_model.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
            filter_proxy_model.setFilterKeyColumn(0)
    
            # Campo da caixa de pesquisa
            search_filed = QtWidgets.QLineEdit()
            search_filed.setStyleSheet('font-size: 16px; height: 30px;', )  # Estilo/Escala da caixa de pesquisa
            search_filed.textChanged.connect(filter_proxy_model.setFilterRegExp)
            mainLayout.addWidget(search_filed)
    
            # Campo da tela de vista
            table = QtWidgets.QListView()
            
            table.setStyleSheet('font-size: 16px; ')
    
            #table.verticalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
            #table.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Stretch)
            table.setModel(filter_proxy_model)
            mainLayout.addWidget(table)
    
    
            self.setLayout(mainLayout)
        
    
        def closeEvent(self, e):
            e.ignore()
            question_close = QtWidgets.QMessageBox.question(self, "Fechamento", "Deseja realmente fechar a aplicação?",  QtWidgets.QMessageBox.Yes,  QtWidgets.QMessageBox.No)
            if question_close ==  QtWidgets.QMessageBox.Yes:
                exit(0)
    
    
    app = QtWidgets.QApplication(sys.argv)
    foxy = FoxyQuizz()
    foxy.show()
    sys.exit(app.exec_())
    
    

    img1.png

    I wanted to change the colors that were shown in the table, green (true), red (false).

    like this

    codigo1_LI.jpg


  • Lifetime Qt Champion

    Do you want the text color to change only when filtering ?



  • @SGaist said in set color(green/red) in conditions bool in listview:

    Do you want the text color to change only when filtering ?

    It could also be.
    I wanted it to work like I did on listwidget:

    img2.png

    however, listwidget does not work with models.
    the text box (QlineEdite) is just a keyword search system.


  • Lifetime Qt Champion

    QListWidget has an internal model.

    For your use case, you can already set the color of your entries when filling the model so no need to fiddle with it when doing your filtering.



  • @SGaist said in set color(green/red) in conditions bool in listview:

    QListWidget has an internal model.
    For your use case, you can already set the color of your entries when filling the model so no need to fiddle with it when doing your filtering.

    when I use lista.setModel (filter_proxy_model)

    returns error:
    Exception has occurred: TypeError
    QListWidget.setModel () is a private method


  • Lifetime Qt Champion

    As I wrote, QListWidget has an internal model. Using QListView with a QStandardItemModel and QSortFilterProxyModel is the correct way to implement what you want.



  • @SGaist said in set color(green/red) in conditions bool in listview:

    QSortFilterProxyModel

    how do I do that?


  • Lifetime Qt Champion

    Do what ? Use QSortFilterProxyModel on top of a QStandardItemModel before a QListView ?



  • @rodrigoml Do you want something like the following? Your explanation is not very clear:

    import sys
    from PyQt5.QtWidgets import (
        QApplication,
        QListWidgetItem,
        QListWidget,
        QLineEdit,
        QVBoxLayout,
        QWidget,
        QMainWindow,
        QListView,
    )
    from PyQt5.QtCore import Qt, QSortFilterProxyModel
    from PyQt5.QtGui import QStandardItemModel, QStandardItem
    import pandas as pd
    
    
    class MainWindow(QWidget):
        def __init__(self):
            super().__init__()
    
            self.setWindowTitle("Foxy Quizz")
            self.resize(480, 600)
    
            d = {"Perguntas": ["P1", "P2", "P3"], "Respostas": [True, False, True]}
    
            pf = pd.DataFrame(d)
            print(pf)
    
            model = QStandardItemModel(0, 1)
            view = QListView()
    
            filter_proxy_model = QSortFilterProxyModel()
            filter_proxy_model.setSourceModel(model)
            filter_proxy_model.setFilterCaseSensitivity(Qt.CaseInsensitive)
            filter_proxy_model.setFilterKeyColumn(0)
    
            view.setModel(filter_proxy_model)
    
            for question, status in zip(pf["Perguntas"], pf["Respostas"]):
                item = QStandardItem(question)
                item.setForeground(Qt.red if status else Qt.green)
                item.setEditable(False)
                model.appendRow(item)
    
            search_box = QLineEdit()
            search_box.textChanged.connect(filter_proxy_model.setFilterRegExp)
            mainLayout = QVBoxLayout(self)
            mainLayout.addWidget(search_box)
            mainLayout.addWidget(view)
    
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
    
        demo = MainWindow()
        demo.show()
    
        sys.exit(app.exec_())
    


  • @eyllanesc said in set color(green/red) in conditions bool in listview:

    import sys
    from PyQt5.QtWidgets import (
    QApplication,
    QListWidgetItem,
    QListWidget,
    QLineEdit,
    QVBoxLayout,
    QWidget,
    QMainWindow,
    QListView,
    )
    from PyQt5.QtCore import Qt, QSortFilterProxyModel
    from PyQt5.QtGui import QStandardItemModel, QStandardItem
    import pandas as pd

    class MainWindow(QWidget):
    def init(self):
    super().init()

        self.setWindowTitle("Foxy Quizz")
        self.resize(480, 600)
    
        d = {"Perguntas": ["P1", "P2", "P3"], "Respostas": [True, False, True]}
    
        pf = pd.DataFrame(d)
        print(pf)
    
        model = QStandardItemModel(0, 1)
        view = QListView()
    
        filter_proxy_model = QSortFilterProxyModel()
        filter_proxy_model.setSourceModel(model)
        filter_proxy_model.setFilterCaseSensitivity(Qt.CaseInsensitive)
        filter_proxy_model.setFilterKeyColumn(0)
    
        view.setModel(filter_proxy_model)
    
        for question, status in zip(pf["Perguntas"], pf["Respostas"]):
            item = QStandardItem(question)
            item.setForeground(Qt.red if status else Qt.green)
            item.setEditable(True)
            model.appendRow(item)
    
        search_box = QLineEdit()
        search_box.textChanged.connect(filter_proxy_model.setFilterRegExp)
        mainLayout = QVBoxLayout(self)
        mainLayout.addWidget(search_box)
        mainLayout.addWidget(view)
    

    if name == "main":
    app = QApplication(sys.argv)

    demo = MainWindow()
    demo.show()
    
    sys.exit(app.exec_())
    

    That's right!! Thanks, I spent days studying, and I couldn't.



  • @rodrigoml The problem with your original code is the line: model.setItem(0, item) since you always set the items to the first row.


Log in to reply