1

How can I make a custom widget (derived from "QFrame") contain a support to be checkable/toggleble? How to make Qt's stylesheet (CSS) to be aware that my widget was checked/toggled by user?

Is there some kind of signal or property that I need to use in my custom widget?

I don't want to use (i.e.) QPushButton because I need my button widget to use Qt's .ui file.

I.e. when using QPushButton - things are simple:

QPushButton#btnName:focus:pressed { border-image: url(ThemesPathKey/menu-top-h.png);    }
QPushButton#btnName:checked {   border-image: url(ThemesPathKey/menu-top-h.png);    }
QPushButton#btnName:hover { border-image: url(ThemesPathKey/menu-top-h.png);    }

I need something similar for my custom button widget.

Thanks.

Gediminas
  • 1,830
  • 3
  • 27
  • 47

2 Answers2

2

You can use hover and focus for a custom widget, but checked is supported for buttons and check boxes only.

To replace checked you can use a custom property:

QPushButton#btnName[checked="true"] {   border-image: url(ThemesPathKey/menu-top-h.png);    }

when your widget is clicked toggle checked property like this:

void mousePressEvent(QMouseEvent*) override
{
    bool checked = property("checked").toBool();
    setProperty("checked", !checked);
    style()->polish(this);
}
Ezee
  • 4,214
  • 1
  • 14
  • 29
  • Thanks Ezee. This is the best way I can think of so far.. Just was really interested ("just for sport") if there is any way to replicate same "checked" action as used in QPushButton. (To use "QFrame#btnName:checked { }" instead of "QFrame#btnName[checked="true"] { }") – Gediminas Nov 13 '14 at 14:15
  • It you want to use a widget different from `QAbstractButton` descendant this is the only way, but you can inherit from `QAbstractButton` and implement your own appearance. In this way I believe you'll be able to manage to use `:checked`. – Ezee Nov 13 '14 at 14:28
  • For "QAbstractButton" you would need to implement your own "paintEvent". And I believe this type of widget would not be usable as a "promotable" widget in the "Qt Creator". Anyway, thanks for the help! I will stick with using "setProperty". – Gediminas Nov 13 '14 at 14:50
1

For hovering, you could use the same approach with any derived widget:

class MyClass : public QFrame
{
<...>
}

MyClass a;
a.setStyleSheet("MyClassa:hover{<...>}"); //this will work
a.setStyleSheet("MyClass#a:hover{<...>}"); //and this will work
a.setStyleSheet("QFrame:hover{<...>}"); //Even this will work, too

Checking/unchecking is more complex. Frames do not have check states, so you'll have to implement it yourself.

class MyClass : public QFrame
{
public:
    <...>
protected:
    void mousePressEvent(QMouseEvent * e) override
    {
        checked_ = !checked_;        
        if(checked)
            setStyleSheet("border:1px solid black;");
        else
            setStyleSheet("border:0px;"); 
    }
bool checked_;
}

or something like this

class MyClass : public QFrame
{
public:
    <...>
protected:
    void paintEvent(QPaintEvent * e) override
    {
        if(checked)
        {
        //draw something
        }
        else
        {
        //draw something else
        }
    }
    bool checked_;
}
SingerOfTheFall
  • 29,228
  • 8
  • 68
  • 105