Font property not working on QListView item sub-control



  • Hi,

    I can't get the font property to work on a QListView item sub-control with the following code:

    #include <QApplication>
    #include <QListView>
    #include <QFileSystemModel>
    
    // Herited model with all items flagged as disabled except the first one
    class Model : public QFileSystemModel
    {
        public:
            Model() : QFileSystemModel() { }
            Qt::ItemFlags flags(const QModelIndex &index) const
            {
                if(index.row() > 0)
                    return Qt::NoItemFlags;
                else
                    return QFileSystemModel::flags(index);
            }
    };
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
    
        QListView v;
        Model* m = new Model;
        m->setRootPath("/");
        v.setModel(m);
        v.setRootIndex(m->index("/"));
    
        // STYLE
        QString style = "";
    
        style += "QListView { ";
        style += "background: lightgrey;";
        style += "}";
    
        style += "QListView::item { ";
        style += "font: bold italic large \"Arial\";"; // Font doesn't work
        style += "height: 40px;"; // Height works
        style += "}";
    
        style += "QListView::item:disabled { ";
        style += "color: blue;"; // Color works
        style += "font: bold italic large \"Times New Roman\";"; // Font doesn't work
        style += "}";
    
        v.setStyleSheet(style);
    
        v.show();
    
        return a.exec();
    }
    

    As written in the comments, the height property works perfectly fine and the color property with a pseudo-state too.
    But the font property does not work (with or without a pseudo-state) with the item sub-control.
    (Example: I want to set a font property different to disabled items)

    Any ideas?


  • Moderators

    Hi, welcome to devnet.

    Yup, stylesheets often have blind spots like that. You can sorta workaround it with a simple delegate:

    struct Delegate : public QStyledItemDelegate {
        Delegate(QObject* parent = nullptr) : QStyledItemDelegate(parent) {}
        void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const {
            QStyleOptionViewItem opt(option);
            if((opt.state & QStyle::State_Enabled) == 0)
                opt.font = QFont( /* whatever you want */ );
    
            QStyledItemDelegate::paint(painter, opt, index);
        }
    };
    

    Btw. Not related to the question but you should really avoid creating strings like that. String addition is an expensive operation and you do a massive amount of reallocations this way.
    Instead of

    QString foo = ""; //this does the same as just QString foo; but is lot more expensive
    foo +=        "bar";
    foo +=        "bazz";
    

    You can write

    QString foo = ""
                  "bar"
                  "bazz";
    

    and this is glued together at compile time by the parser instead of being an expensive operation at runtime.
    If you use C++11 it gets even better with raw string literals:

    QString foo = R"(
    bar
    bazz
    ");
    

    as you don't have to quote every line and you can use unescaped characters and quotes inside.



  • Hi,

    I guess I will have to use a delegate :)
    And thanks for the QString tips!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.