Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QTreeView & QStyledItemDelegate & QPushButton/Checkbox etc?

QTreeView & QStyledItemDelegate & QPushButton/Checkbox etc?

Scheduled Pinned Locked Moved Unsolved General and Desktop
qtreeviewqpushbuttonqstyleditemdelecheckbox
20 Posts 2 Posters 9.9k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Dariusz
    27 Mar 2019, 17:17

    Hey

    I'm currently studying QStyledItemDelegate and how it operates. I roughly understand how the editor happens, but I do wonder how can I create a delegate for a constantly active widget? Like .... pushButton ? checkbox/ radio button etc etc?

    I found some tutorials on spinner/star rating/color combobox etc etc... but not much on "active widgets"

    I found this one > https://qtadventures.wordpress.com/2012/02/04/adding-button-to-qviewtable/ Which looks interesting. He takes a picture of a button and displays that as far as I can tell + links other stuff to it + there seems to be only 1 widget for all rows/columns? Soo... I guess efficient? No need to create lots of widgets...

    I do wonder if that is the best way to do it?

    Say my treeView will have 20x600 columns/rows and out of 20 columns about 5 will be widget based... is this the best solution ? Take pixmaps of it all per type/column/row and then "hack" it together?

    In which case my second question is, what is the proper way of creating widgets? I know there is some kind of style delegate/object something that I can use to generate a "look" of a widget, I used to try to learn it about a year ago(No idea now what was what). I think I was trying to paint a checkbox in QGraphicsView etc and that was the idea. Maybe I can use the same creation system here for widgets? As I need events like hover/highlight/pressed etc etc... hmmmm

    I think it was QStyleOption something, setOption to QPushButton, and then draw/render it? Tricky... bad memory.

    TIA

    R Offline
    R Offline
    raven-worx
    Moderators
    wrote on 27 Mar 2019, 17:37 last edited by
    #2

    @Dariusz said in QTreeView & QStyledItemDelegate & QPushButton/Checkbox etc?:

    I do wonder if that is the best way to do it?

    for anything other than checkboxes (there is already built-in support) this is the most perfomant way.
    Hold one instance of the widget and initialize it and paint it with QWidget::render() (no need to render it in.a pixmap).
    The hover state must be handled by you though by checking if the mous is over the area you paint the widget at.

    I disencourage to use of QTableView::setIndexWidget() for performance reasons.

    --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
    If you have a question please use the forum so others can benefit from the solution in the future

    1 Reply Last reply
    1
    • D Offline
      D Offline
      Dariusz
      wrote on 27 Mar 2019, 17:56 last edited by
      #3

      @raven-worx said in QTreeView & QStyledItemDelegate & QPushButton/Checkbox etc?:

      for anything other than checkboxes (there is already built-in support) this is the most perfomant way.
      Hold one instance of the widget and initialize it and paint it with QWidget::render() (no need to render it in.a pixmap).
      The hover state must be handled by you though by checking if the mous is over the area you paint the widget at.

      Hmm a little confused here... When you say for anything other than checkboxes there is built in support, what do you mean by this ?

      Hold one instance of the widget and initialize it and paint it with QWidget::render() (no need to render it in.a pixmap).

      I take I need a map/list something with all widgets then to call ->render on them at any time ? I do wonder now however how I can handle different labels on widgets, perhaps I will need to do widget->setText(),widget->render() in the paint event ?

      The hover state must be handled by you though by checking if the mous is over the area you paint the widget at.

      So do I detect it in the paint event? like paint (...){ visualRect(index).contains(mousePos) ? if true > highlight/else normal ?}

      @raven-worx said in QTreeView & QStyledItemDelegate & QPushButton/Checkbox etc?:

      I disencourage to use of QTableView::setIndexWidget() for performance reasons.

      I think this is why I was trying to learn the QStyleItemDelegate... to generate the view in more optimized "way"

      R 1 Reply Last reply 27 Mar 2019, 18:03
      0
      • D Dariusz
        27 Mar 2019, 17:56

        @raven-worx said in QTreeView & QStyledItemDelegate & QPushButton/Checkbox etc?:

        for anything other than checkboxes (there is already built-in support) this is the most perfomant way.
        Hold one instance of the widget and initialize it and paint it with QWidget::render() (no need to render it in.a pixmap).
        The hover state must be handled by you though by checking if the mous is over the area you paint the widget at.

        Hmm a little confused here... When you say for anything other than checkboxes there is built in support, what do you mean by this ?

        Hold one instance of the widget and initialize it and paint it with QWidget::render() (no need to render it in.a pixmap).

        I take I need a map/list something with all widgets then to call ->render on them at any time ? I do wonder now however how I can handle different labels on widgets, perhaps I will need to do widget->setText(),widget->render() in the paint event ?

        The hover state must be handled by you though by checking if the mous is over the area you paint the widget at.

        So do I detect it in the paint event? like paint (...){ visualRect(index).contains(mousePos) ? if true > highlight/else normal ?}

        @raven-worx said in QTreeView & QStyledItemDelegate & QPushButton/Checkbox etc?:

        I disencourage to use of QTableView::setIndexWidget() for performance reasons.

        I think this is why I was trying to learn the QStyleItemDelegate... to generate the view in more optimized "way"

        R Offline
        R Offline
        raven-worx
        Moderators
        wrote on 27 Mar 2019, 18:03 last edited by
        #4

        When you say for anything other than checkboxes there is built in support, what do you mean by this ?

        if the model supports it (checkstate role and checkable item-flag) the standard delegates already renders a checkbox in the itemview in the cell.
        see the example in https://doc.qt.io/qt-5/modelview.html

        perhaps I will need to do widget->setText(),widget->render() in the paint event ?

        yes thats what i meant.

        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
        If you have a question please use the forum so others can benefit from the solution in the future

        1 Reply Last reply
        0
        • D Offline
          D Offline
          Dariusz
          wrote on 27 Mar 2019, 18:20 last edited by Dariusz
          #5

          Hey

          This is turning out to be quite fun!

          So far I got this running in a test :

          https://pasteboard.co/I7otT7J.gif

          I do however struggle to wrap my head around why the position of drawn button is wrong? It seems like its offseted by 1 item ?

          Also why do I have paint errors? Kidna worrying.

          On the other front I realized that I dont have to do any detection at all, just use option.flags to see what flag is being active and based on this I can define what to do with my button, yay!!! Amazing :- )

          Thanks for tutorial... in all the time I'm studying the model/view system this is the 1st I see it... wow.

          TIA

          ps. And I have no idea how to handle click event... yet... ;- ) and I think I got it... editorEvent? :D

          R 1 Reply Last reply 27 Mar 2019, 18:26
          0
          • D Dariusz
            27 Mar 2019, 18:20

            Hey

            This is turning out to be quite fun!

            So far I got this running in a test :

            https://pasteboard.co/I7otT7J.gif

            I do however struggle to wrap my head around why the position of drawn button is wrong? It seems like its offseted by 1 item ?

            Also why do I have paint errors? Kidna worrying.

            On the other front I realized that I dont have to do any detection at all, just use option.flags to see what flag is being active and based on this I can define what to do with my button, yay!!! Amazing :- )

            Thanks for tutorial... in all the time I'm studying the model/view system this is the 1st I see it... wow.

            TIA

            ps. And I have no idea how to handle click event... yet... ;- ) and I think I got it... editorEvent? :D

            R Offline
            R Offline
            raven-worx
            Moderators
            wrote on 27 Mar 2019, 18:26 last edited by
            #6

            @Dariusz said in QTreeView & QStyledItemDelegate & QPushButton/Checkbox etc?:

            I do however struggle to wrap my head around why the position of drawn button is wrong? It seems like its offseted by 1 item ?

            It might be that the painter is already translated (i cant remember exactly). This would make the parameter from the render() method call superfluous.

            On the other front I realized that I dont have to do any detection at all, just use option.flags to see what flag is being active and based on this I can define what to do with my button, yay!!! Amazing :- )

            this flag is set when the mouse is over the cell, not directly over the widget. If thats ok for you you can use it of course.

            --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
            If you have a question please use the forum so others can benefit from the solution in the future

            D 1 Reply Last reply 27 Mar 2019, 20:11
            0
            • R raven-worx
              27 Mar 2019, 18:26

              @Dariusz said in QTreeView & QStyledItemDelegate & QPushButton/Checkbox etc?:

              I do however struggle to wrap my head around why the position of drawn button is wrong? It seems like its offseted by 1 item ?

              It might be that the painter is already translated (i cant remember exactly). This would make the parameter from the render() method call superfluous.

              On the other front I realized that I dont have to do any detection at all, just use option.flags to see what flag is being active and based on this I can define what to do with my button, yay!!! Amazing :- )

              this flag is set when the mouse is over the cell, not directly over the widget. If thats ok for you you can use it of course.

              D Offline
              D Offline
              Dariusz
              wrote on 27 Mar 2019, 20:11 last edited by Dariusz
              #7

              @raven-worx said in QTreeView & QStyledItemDelegate & QPushButton/Checkbox etc?:

              this flag is set when the mouse is over the cell, not directly over the widget. If thats ok for you you can use it of course.

              Hmm yea good question... I guess I would want to detect a more precise location of what is what...

              Also I'm in editorEvent(), I got my event type detected, but how can I then pass that to my paint() function ? Say I want to do button pressed / released change ?

              I tried with this in editorEvent()

                  switch (event->type()) {
                      case (QEvent::MouseButtonPress): {
                          qobject_cast<QPushButton *>(mWidgetList[0])->setText("PRESSED?");
                          break;
                      }
                      case (QEvent::MouseButtonRelease): {
                          qobject_cast<QPushButton *>(mWidgetList[0])->setText("Released?");
                          break;
                      }
                  }
              

              But I'm getting "random" draw updates and lots of paint bugs. the paint bugs I posted above still persist... not sure what to do with them.

              I was reading source for past 1hand oh boy my head is spinning... still fairly lost with the complexity of what happens there - mainly qcheckbox example/etc that are implemented...

              I think I need to call paint() with my own argument list and flags to make sure I paint the button with right flag... or maybe use editorEvent to set data on my index to xxx and read that data in paint event and act accordingly?



              Ok so it seems that in editorEvent I set the flags in my index.data and then in paint event I need to read them all and act accordingly. Woah thats a lot of setters/getters o.o But I can draw anything I want and its just draw calls so hopefully no heavy logic except for bunch of if/else statements? o.O



              Ok so now that I can somehow "mostly" style what I want how I want. What if I now want to call a function depending on the button I press on ? Do I store a function call/lambda in a QVariant and then retrieve it somehow and call with arguments? Or maybe just call Q_EMIT mySingla_PressedAndReleased(index)? and hock up signals to QDelegate? I wonder...hmmmmmm

              R 1 Reply Last reply 27 Mar 2019, 20:47
              0
              • D Dariusz
                27 Mar 2019, 20:11

                @raven-worx said in QTreeView & QStyledItemDelegate & QPushButton/Checkbox etc?:

                this flag is set when the mouse is over the cell, not directly over the widget. If thats ok for you you can use it of course.

                Hmm yea good question... I guess I would want to detect a more precise location of what is what...

                Also I'm in editorEvent(), I got my event type detected, but how can I then pass that to my paint() function ? Say I want to do button pressed / released change ?

                I tried with this in editorEvent()

                    switch (event->type()) {
                        case (QEvent::MouseButtonPress): {
                            qobject_cast<QPushButton *>(mWidgetList[0])->setText("PRESSED?");
                            break;
                        }
                        case (QEvent::MouseButtonRelease): {
                            qobject_cast<QPushButton *>(mWidgetList[0])->setText("Released?");
                            break;
                        }
                    }
                

                But I'm getting "random" draw updates and lots of paint bugs. the paint bugs I posted above still persist... not sure what to do with them.

                I was reading source for past 1hand oh boy my head is spinning... still fairly lost with the complexity of what happens there - mainly qcheckbox example/etc that are implemented...

                I think I need to call paint() with my own argument list and flags to make sure I paint the button with right flag... or maybe use editorEvent to set data on my index to xxx and read that data in paint event and act accordingly?



                Ok so it seems that in editorEvent I set the flags in my index.data and then in paint event I need to read them all and act accordingly. Woah thats a lot of setters/getters o.o But I can draw anything I want and its just draw calls so hopefully no heavy logic except for bunch of if/else statements? o.O



                Ok so now that I can somehow "mostly" style what I want how I want. What if I now want to call a function depending on the button I press on ? Do I store a function call/lambda in a QVariant and then retrieve it somehow and call with arguments? Or maybe just call Q_EMIT mySingla_PressedAndReleased(index)? and hock up signals to QDelegate? I wonder...hmmmmmm

                R Offline
                R Offline
                raven-worx
                Moderators
                wrote on 27 Mar 2019, 20:47 last edited by raven-worx
                #8

                @Dariusz
                editorEvent() is completly wrong and the fact that it actually gets called in your case makes it suspicious that there is more wrong in your code.

                Also it seems that you are using multiple widget instances (mWidgetList)? Thats also not as i sugested.

                Forget about the hover over the widget boundaries for now, that overcomplicates the whole implementation.
                To achieve what you want, you need to "bind" the item view widget to the delegate (e.g. by passing a pointer to the delegate). The view need to request the painting of the delegate. So you need to call QAbstractItemView::update(index); to request a paint event in the delegate. So actually you can override the viewportEvent() of the item view widget, and react on the events you want (mouse hover/move and press). Alternatively if you do not want to subclass an item view widget you can install an eventfilter on the QAbstractItemView::viewport() widget.

                So far so good.

                So you hold a single widget instance you want to paint in your delegate and initialize this widget everytime just before you paint it. Now the challenge is how to pass the states/properties of the widget for the cell you currently paint.

                Complete different approach:
                Add a widget as a child of the QAbstractItemView::viewport() widget. This widget is hidden, unless you hover ofer the viewport and get the index with QAbstractItemView::indexAt(mousEvent->pos()); Then you have a full functional clickable widget positioned with QAbstractItemView::visualRect(indexUnderMouse)

                --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                If you have a question please use the forum so others can benefit from the solution in the future

                1 Reply Last reply
                1
                • D Offline
                  D Offline
                  Dariusz
                  wrote on 27 Mar 2019, 20:51 last edited by Dariusz
                  #9

                  Hmmmmmmmmmmmmmmmmmmm what did I dooo....

                  @raven-worx said in QTreeView & QStyledItemDelegate & QPushButton/Checkbox etc?:

                  Also it seems that you are using multiple widget instances (mWidgetList)? Thats also not as i sugested.

                  Well I dont call it myself, it just gets fired when I click on a cell. I guess qt uses it to see if I clicked or 2x clicked or click & drag and then determines some action ?

                  mWidgetList = {QPushButton, QLineEdit, QListView, QTableView, QCheckBox,etc,etc}
                  So I use 
                  switch(index.data(myRole){
                      case (pushButton):
                               int state = index.data(stateRole)
                               if (state){
                                    mmWidgetList[0]->setPressed()/->render() later
                                else{
                                    draw unpressed 
                                       }
                  

                  etc etc. So I use editorEvent to set click states, and then paint event to retrieve them properly... depending on widget/cell/type


                  I'll get back with more info in a bit, I accidentally pressed submit... so I'm still reading/trying to understand what you have posted :- )


                  I only use 1 widget pert type in my list. All of which that can be represented in my treeView. I just have them nicely stored in a list map so I can use maybe index.data(widgetRole) to show the correct widget by role type...

                  1 Reply Last reply
                  0
                  • D Offline
                    D Offline
                    Dariusz
                    wrote on 28 Mar 2019, 17:13 last edited by
                    #10

                    A bit of a follow up.. this time a bit more on style side... I stopped using QWidgets for them moment and went with pure style drawing for the moment... "scary" stuff, but I hit a wall with styles. I can't get it to paint the way my style sheet is set. I set my setyle on app via:

                            f.open(QFile::ReadOnly | QFile::Text);
                            QTextStream ts(&f);
                            qApp->setStyleSheet(ts.readAll());
                    

                    In my main.cpp function, and here are my tries with button drawing :

                                QStyleOptionButton button;
                                //button.initFrom(option.widget);
                                button.state = option.state;// QStyle::State_Active | QStyle::State_Enabled; // State_Sunken    `
                                button.direction = QApplication::layoutDirection();
                                button.rect = option.rect;
                                button.text = "HEy Sexy";
                                //button.palette = option.palette;
                                button.features = QStyleOptionButton::AutoDefaultButton;
                                //button.styleObject = QApplication::style();
                                //button.fontMetrics = QApplication::fontMetrics();
                                QApplication::style()->drawControl(QStyle::CE_PushButton, &button, painter);
                    

                    The // parts are what I tried to use, but so far no luck...

                    The button does not follow the style set by stylesheet... what can I do to make it style properly?

                    Regards
                    Dariusz

                    TIA

                    R 1 Reply Last reply 28 Mar 2019, 18:56
                    0
                    • D Dariusz
                      28 Mar 2019, 17:13

                      A bit of a follow up.. this time a bit more on style side... I stopped using QWidgets for them moment and went with pure style drawing for the moment... "scary" stuff, but I hit a wall with styles. I can't get it to paint the way my style sheet is set. I set my setyle on app via:

                              f.open(QFile::ReadOnly | QFile::Text);
                              QTextStream ts(&f);
                              qApp->setStyleSheet(ts.readAll());
                      

                      In my main.cpp function, and here are my tries with button drawing :

                                  QStyleOptionButton button;
                                  //button.initFrom(option.widget);
                                  button.state = option.state;// QStyle::State_Active | QStyle::State_Enabled; // State_Sunken    `
                                  button.direction = QApplication::layoutDirection();
                                  button.rect = option.rect;
                                  button.text = "HEy Sexy";
                                  //button.palette = option.palette;
                                  button.features = QStyleOptionButton::AutoDefaultButton;
                                  //button.styleObject = QApplication::style();
                                  //button.fontMetrics = QApplication::fontMetrics();
                                  QApplication::style()->drawControl(QStyle::CE_PushButton, &button, painter);
                      

                      The // parts are what I tried to use, but so far no luck...

                      The button does not follow the style set by stylesheet... what can I do to make it style properly?

                      Regards
                      Dariusz

                      TIA

                      R Offline
                      R Offline
                      raven-worx
                      Moderators
                      wrote on 28 Mar 2019, 18:56 last edited by raven-worx
                      #11

                      @Dariusz
                      unfortunately thats only possible with a QWidget instance again, since only QWidgets get polished by styles.
                      Also read this.
                      So either you pass a QPushButton to the drawControl() method or use a QStylePainter instead. But which is impossible, since only 1 painter at the time can be active for a paint device (the viewport in this case).

                      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                      If you have a question please use the forum so others can benefit from the solution in the future

                      1 Reply Last reply
                      2
                      • D Offline
                        D Offline
                        Dariusz
                        wrote on 28 Mar 2019, 23:50 last edited by
                        #12

                        That is a very strange thing that we can create a QStyleOptionButton and then NOT be able to use the styleSheet to style that button by default... ?

                        It seems if I do this :

                                    const QWidget *widget = option.widget;
                                    QStyle *style = widget ? widget->style() : QApplication::style();
                                    QApplication::style()->drawControl(QStyle::CE_PushButton, &button, painter, widget );
                        

                        or even this:

                                    QApplication::style()->drawControl(QStyle::CE_PushButton, &button, painter, option.widget);
                        
                        

                        I get some "kind" of styling from my styleSheet, but the button doesn't look like button sadly. Once I pass parrent widget, it seems like he uses the right Palette but something breaks?

                        Then I tried this, which "kinda" does something but still not a button...

                                    QPushButton *b = new QPushButton();
                                    QStyleOptionButton button;
                                    button.initFrom(b);
                                    QApplication::style()->drawControl(QStyle::CE_PushButton, &button, painter, b);
                        

                        Which is very strange, as I'm creating style based on a widget so why would it not look correct?

                        So it seems that I'm back to using a widget for my painting... which kinda seems counter "productive". Or perhaps I need to learn how to style each part of the button and just style them precisely by hand...

                        Right now I get this https://pasteboard.co/I7zYlPz.gif
                        with this method :

                                QApplication::style()->drawControl(QStyle::CE_PushButton, &button, painter, option.widget);
                        

                        If I wish to style this as a button - ie add the correct background color/bevels/round edges etc. Where do I do this ?

                        TIA

                        R 1 Reply Last reply 29 Mar 2019, 08:19
                        0
                        • D Dariusz
                          28 Mar 2019, 23:50

                          That is a very strange thing that we can create a QStyleOptionButton and then NOT be able to use the styleSheet to style that button by default... ?

                          It seems if I do this :

                                      const QWidget *widget = option.widget;
                                      QStyle *style = widget ? widget->style() : QApplication::style();
                                      QApplication::style()->drawControl(QStyle::CE_PushButton, &button, painter, widget );
                          

                          or even this:

                                      QApplication::style()->drawControl(QStyle::CE_PushButton, &button, painter, option.widget);
                          
                          

                          I get some "kind" of styling from my styleSheet, but the button doesn't look like button sadly. Once I pass parrent widget, it seems like he uses the right Palette but something breaks?

                          Then I tried this, which "kinda" does something but still not a button...

                                      QPushButton *b = new QPushButton();
                                      QStyleOptionButton button;
                                      button.initFrom(b);
                                      QApplication::style()->drawControl(QStyle::CE_PushButton, &button, painter, b);
                          

                          Which is very strange, as I'm creating style based on a widget so why would it not look correct?

                          So it seems that I'm back to using a widget for my painting... which kinda seems counter "productive". Or perhaps I need to learn how to style each part of the button and just style them precisely by hand...

                          Right now I get this https://pasteboard.co/I7zYlPz.gif
                          with this method :

                                  QApplication::style()->drawControl(QStyle::CE_PushButton, &button, painter, option.widget);
                          

                          If I wish to style this as a button - ie add the correct background color/bevels/round edges etc. Where do I do this ?

                          TIA

                          R Offline
                          R Offline
                          raven-worx
                          Moderators
                          wrote on 29 Mar 2019, 08:19 last edited by
                          #13

                          @Dariusz
                          of course it heavily depends how your stylesheet looks like.
                          The button from your screenshot looks like it is styled by stylesheet style. So you will rather think about your style rules.

                          --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                          If you have a question please use the forum so others can benefit from the solution in the future

                          1 Reply Last reply
                          0
                          • D Offline
                            D Offline
                            Dariusz
                            wrote on 30 Mar 2019, 18:30 last edited by
                            #14

                            Hmmm Ok I did more tests, it seems that my button does work as it should! I just didnt notice my style was so meh...

                            Ok so moving on.... kinda...
                            I now can style stuff the way I want via stylesheet... I'm slowly learning more and more about QStyle... something I wonder...

                            I know I can specify some custom qss commands, like widget name or something like that can apply to a specific widget... however I do wonder if there is a way to add a custom property/color?

                            Say I have a 3 flags for atext, on/off/danger, green/red/orange colors, Is there a way to somehow grab a property from styleSheet and then use it for color during my paint event? I know I could hard code the colors, but I would rather have a more "fancy" stylesheet here if I can.

                            I tried doing this :

                            qss.
                            QMagic{
                            qproperty-MAGIC : 10;
                            }

                            qDebug() << qApp->style()->property("qproperty-MAGIC");

                            But I'm fairly sure I did something wrong... was trying to follow : https://stackoverflow.com/questions/36125907/adding-new-stylesheet-parameters-for-custom-qt-widgets

                            Any help would be great.

                            TIA

                            R 1 Reply Last reply 30 Mar 2019, 19:55
                            0
                            • D Dariusz
                              30 Mar 2019, 18:30

                              Hmmm Ok I did more tests, it seems that my button does work as it should! I just didnt notice my style was so meh...

                              Ok so moving on.... kinda...
                              I now can style stuff the way I want via stylesheet... I'm slowly learning more and more about QStyle... something I wonder...

                              I know I can specify some custom qss commands, like widget name or something like that can apply to a specific widget... however I do wonder if there is a way to add a custom property/color?

                              Say I have a 3 flags for atext, on/off/danger, green/red/orange colors, Is there a way to somehow grab a property from styleSheet and then use it for color during my paint event? I know I could hard code the colors, but I would rather have a more "fancy" stylesheet here if I can.

                              I tried doing this :

                              qss.
                              QMagic{
                              qproperty-MAGIC : 10;
                              }

                              qDebug() << qApp->style()->property("qproperty-MAGIC");

                              But I'm fairly sure I did something wrong... was trying to follow : https://stackoverflow.com/questions/36125907/adding-new-stylesheet-parameters-for-custom-qt-widgets

                              Any help would be great.

                              TIA

                              R Offline
                              R Offline
                              raven-worx
                              Moderators
                              wrote on 30 Mar 2019, 19:55 last edited by raven-worx
                              #15

                              @Dariusz
                              QWidgets do not get polished when a custom property changes.
                              So whenever you change a property in C++ which should affect the styling you need to call:

                              MyWidget::setMyColorProperty(QString value)
                              {
                                 mColor = QColor(value);
                                 this->update();
                              }
                              ....
                              widget->setProperty("customPropertyName", "danger");
                              widget->style()->polish(widget);
                              

                              In QSS:

                              MyWidget[customPropertyName="danger"] {
                                 qproperty-myColorProperty: "red";
                              }
                              

                              --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                              If you have a question please use the forum so others can benefit from the solution in the future

                              D 1 Reply Last reply 30 Mar 2019, 21:43
                              2
                              • R raven-worx
                                30 Mar 2019, 19:55

                                @Dariusz
                                QWidgets do not get polished when a custom property changes.
                                So whenever you change a property in C++ which should affect the styling you need to call:

                                MyWidget::setMyColorProperty(QString value)
                                {
                                   mColor = QColor(value);
                                   this->update();
                                }
                                ....
                                widget->setProperty("customPropertyName", "danger");
                                widget->style()->polish(widget);
                                

                                In QSS:

                                MyWidget[customPropertyName="danger"] {
                                   qproperty-myColorProperty: "red";
                                }
                                
                                D Offline
                                D Offline
                                Dariusz
                                wrote on 30 Mar 2019, 21:43 last edited by Dariusz
                                #16

                                @raven-worx Hmmmmmmm still somewhat lost...

                                It seems like its time for me to learn about Q_Property then :- )
                                https://wiki.qt.io/Qt_Style_Sheets_and_Custom_Painting_Example
                                and
                                https://wiki.qt.io/Dynamic_Properties_and_Stylesheets
                                I take this is needed for this to work ?

                                Feels a little...tricky... as I'm failing :- )... still failing... yeah cant get it to work o.O

                                So there is no way to just store a

                                myVariables{
                                someColor : red;
                                otherColor : blue;
                                ninja : black
                                } 
                                

                                and then be able to read it from any widget and set on that widget? A bit like repository of variables?

                                Regards
                                Dariusz
                                TIa

                                R 1 Reply Last reply 30 Mar 2019, 22:23
                                0
                                • D Dariusz
                                  30 Mar 2019, 21:43

                                  @raven-worx Hmmmmmmm still somewhat lost...

                                  It seems like its time for me to learn about Q_Property then :- )
                                  https://wiki.qt.io/Qt_Style_Sheets_and_Custom_Painting_Example
                                  and
                                  https://wiki.qt.io/Dynamic_Properties_and_Stylesheets
                                  I take this is needed for this to work ?

                                  Feels a little...tricky... as I'm failing :- )... still failing... yeah cant get it to work o.O

                                  So there is no way to just store a

                                  myVariables{
                                  someColor : red;
                                  otherColor : blue;
                                  ninja : black
                                  } 
                                  

                                  and then be able to read it from any widget and set on that widget? A bit like repository of variables?

                                  Regards
                                  Dariusz
                                  TIa

                                  R Offline
                                  R Offline
                                  raven-worx
                                  Moderators
                                  wrote on 30 Mar 2019, 22:23 last edited by raven-worx
                                  #17

                                  @Dariusz said in QTreeView & QStyledItemDelegate & QPushButton/Checkbox etc?:

                                  and then be able to read it from any widget and set on that widget?

                                  only if the widget has the property defined.

                                  QWidget {
                                      qproperty-PROP: "red";
                                  }
                                  

                                  This will try to apply the property to all QWidget instances. But will also result in a warning IIRC, when the property isn't defined on the widget..

                                  --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                                  If you have a question please use the forum so others can benefit from the solution in the future

                                  D 1 Reply Last reply 31 Mar 2019, 05:44
                                  0
                                  • R raven-worx
                                    30 Mar 2019, 22:23

                                    @Dariusz said in QTreeView & QStyledItemDelegate & QPushButton/Checkbox etc?:

                                    and then be able to read it from any widget and set on that widget?

                                    only if the widget has the property defined.

                                    QWidget {
                                        qproperty-PROP: "red";
                                    }
                                    

                                    This will try to apply the property to all QWidget instances. But will also result in a warning IIRC, when the property isn't defined on the widget..

                                    D Offline
                                    D Offline
                                    Dariusz
                                    wrote on 31 Mar 2019, 05:44 last edited by Dariusz
                                    #18

                                    @raven-worx Hmmm the delegate is not a widget, can it even access that kind of data?

                                    I'm quite surprised there is no way to just do styleSheet()->getObjectByType("mySomeClassType").getPropertyByName("nameProp") :- (

                                    Edit. I kinda just realized something, I can just do object.styleSheet().getMyValMyselfInMyStyleParser() So I just have to figure out how to parse style sheet and then I can get data I want. I don't even have to use QT system for it except for styleSheet() to get string. Yay!

                                    1 Reply Last reply
                                    0
                                    • D Offline
                                      D Offline
                                      Dariusz
                                      wrote on 31 Mar 2019, 11:06 last edited by Dariusz
                                      #19

                                      Right, so moving on... while I'm R&Ding css parser... ;- )

                                      QCheckBox style of the check box indicator...

                                      I'm struggling to get it to the right place, I'm guessing something in my style sheet messes up something or in my code...

                                      Here is the paint I get : the checkbox is not aligned to my icon.png file... https://pasteboard.co/I7XmA8n.png

                                      cpp.

                                                  QStyleOptionButton opt;
                                                  opt.rect = getCheckBoxrect(option);
                                                  opt.state = option.state;
                                                  if (index.data(enTreeCustomWidgetData)).toBool()) {
                                                      opt.state |= QStyle::State_On;
                                                  } else {
                                                      opt.state |= QStyle::State_Off;
                                                  }
                                                  QApplication::style()->drawControl(QStyle::CE_CheckBox, &opt, painter, option.widget); /// need option.widget for style-look
                                                  opt.text = "bvdfasbdfsbdfs";
                                                  opt.state |= QStyle::State_Enabled;
                                                  QRect r = option.rect;
                                                  r.setTopLeft(opt.rect.topRight() + QPoint(5, -5));
                                                  opt.rect = r;
                                                  QApplication::style()->drawControl(QStyle::CE_CheckBoxLabel, &opt, painter, option.widget);
                                      

                                      getRect.cpp

                                          QStyleOptionButton opt_button;
                                          opt_button.QStyleOption::operator=(option);
                                          QRect sz = QApplication::style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &opt_button, option.widget);
                                          QRect r = option.rect;
                                          r.setTopLeft(r.topLeft() + QPoint(5, 5));
                                          r.setWidth(sz.width());
                                          r.setHeight(sz.height());
                                          return r;
                                      

                                      Style:

                                      
                                      QTreeView::indicator:checked,
                                      QListView::indicator:checked {
                                          image: url(:/qss_icons/rc/checkbox_checked.png);
                                      }
                                      
                                      QTreeView::indicator:unchecked,
                                      QListView::indicator:unchecked {
                                          image: url(:/qss_icons/rc/checkbox_unchecked.png);
                                      }
                                      
                                      QTreeView::indicator:checked:hover,
                                      QTreeView::indicator:checked:focus,
                                      QTreeView::indicator:checked:pressed,
                                      QListView::indicator:checked:hover,
                                      QListView::indicator:checked:focus,
                                      QListView::indicator:checked:pressed {
                                          image: url(:/qss_icons/rc/checkbox_checked_focus.png);
                                      }
                                      
                                      QTreeView::indicator:unchecked:hover,
                                      QTreeView::indicator:unchecked:focus,
                                      QTreeView::indicator:unchecked:pressed,
                                      QListView::indicator:unchecked:hover,
                                      QListView::indicator:unchecked:focus,
                                      QListView::indicator:unchecked:pressed {
                                          image: url(:/qss_icons/rc/checkbox_unchecked_focus.png);
                                      }
                                      
                                      QTreeView::indicator:indeterminate:hover,
                                      QTreeView::indicator:indeterminate:focus,
                                      QTreeView::indicator:indeterminate:pressed,
                                      QListView::indicator:indeterminate:hover,
                                      QListView::indicator:indeterminate:focus,
                                      QListView::indicator:indeterminate:pressed {
                                          image: url(:/qss_icons/rc/checkbox_indeterminate_focus.png);
                                      }
                                      
                                      QTreeView::indicator:indeterminate,
                                      QListView::indicator:indeterminate {
                                          image: url(:/qss_icons/rc/checkbox_indeterminate.png);
                                      }
                                      
                                      QListView,
                                      QTreeView,
                                      QTableView,
                                      QColumnView {
                                          background-color: #19232D;
                                          border: 1px solid #32414B;
                                          color: #F0F0F0;
                                          gridline-color: #32414B;
                                          border-radius: 4px;
                                      }
                                      

                                      What did I break here? :- )

                                      TIA



                                      Ok I cant get it through properly...
                                      Went all the way to > https://code.woboq.org/qt5/qtbase/src/widgets/styles/qcommonstyle.cpp.html#2219
                                      as well as

                                          qDebug() << "SE_CheckBoxIndicator " << QApplication::style()->subElementRect(QStyle::SE_CheckBoxIndicator, &opt_button, option.widget);
                                          qDebug() << "SE_CheckBoxContents  " << QApplication::style()->subElementRect(QStyle::SE_CheckBoxContents, &opt_button, option.widget);
                                          qDebug() << "SE_CheckBoxFocusRect " << QApplication::style()->subElementRect(QStyle::SE_CheckBoxFocusRect, &opt_button, option.widget);
                                          qDebug() << "SE_CheckBoxClickRect " << QApplication::style()->subElementRect(QStyle::SE_CheckBoxClickRect, &opt_button, option.widget);
                                          qDebug() << "SE_ItemViewItemCheckIndicator " << QApplication::style()->subElementRect(QStyle::SE_ItemViewItemCheckIndicator, &opt_button, option.widget);
                                      

                                      None of them returns the correct size of my image that I use in my styleSheet... Something keeps messing up the look of the checkbox.



                                      Ok I gave up on that styleSheet thing with checkbox... ended up with :

                                                      case Qt::Checked: {
                                                          opt.state |= QStyle::State_On;
                                                          if ((opt.state & QStyle::State_MouseOver) || (opt.state & QStyle::State_Selected)) {
                                                              map.load(":/qss_icons/rc/checkbox_checked_focus.png");
                                                          } else if (opt.state & QStyle::State_Selected) {
                                      
                                                          } else {
                                                              map.load(":/qss_icons/rc/checkbox_checked.png");
                                                          }
                                                          break;
                                                      }
                                                      case Qt::PartiallyChecked: {
                                                          opt.state |= QStyle::State_NoChange;
                                                          map.load(":/qss_icons/rc/checkbox_indeterminate.png");
                                                          break;
                                                      }
                                                      case Qt::Unchecked: {
                                                          opt.state |= QStyle::State_Off;
                                                          map.load(":/qss_icons/rc/checkbox_unchecked.png");
                                                          break;
                                                      }
                                                  }
                                                  painter->drawPixmap(opt.rect, map);
                                      

                                      But now I've preloaded it in to map and I'm loading it form map.

                                      In any case... I do wonder however, if I have a widget... can I get it styleSheet parameter? Say I'd like a style of checkbox in QCheckBox of the image for checkbox indicator... can I get the path from Qt ? This way I can use the stylesheet instead of fixed image paths in code... ?

                                      1 Reply Last reply
                                      0
                                      • D Offline
                                        D Offline
                                        Dariusz
                                        wrote on 4 Apr 2019, 19:10 last edited by
                                        #20

                                        Hey

                                        Got a follow up question in regards to styling...

                                        How can I get QComboBox focus indicator/rect ? So that I can set correct color for the outline of comboBox to paint?

                                        I tried using

                                                    QRect r = QApplication::style()->subElementRect(QStyle::SE_ComboBoxLayoutItem, &option, mWidgetList[ComboBox]);
                                        

                                        and

                                                   QRect  r = QApplication::style()->subElementRect(QStyle::SE_ComboBoxFocusRect, &option, mWidgetList[ComboBox]);
                                        

                                        But neither return correct rect to use as paint target... Only the large square one around item in tree view.

                                        Any hints?

                                        Same for QPushButton, and pretty much any button/combo like widget I think o.O

                                        TIA.

                                        1 Reply Last reply
                                        0

                                        11/20

                                        28 Mar 2019, 18:56

                                        • Login

                                        • Login or register to search.
                                        11 out of 20
                                        • First post
                                          11/20
                                          Last post
                                        0
                                        • Categories
                                        • Recent
                                        • Tags
                                        • Popular
                                        • Users
                                        • Groups
                                        • Search
                                        • Get Qt Extensions
                                        • Unsolved