Horst Walter
Horst Walter

Reputation: 14081

How to make QCheckBox readonly, but not grayed-out

Any good way to make a checkbox readonly, but also not grayed-out (hardly visible).

  1. I have used setEnabled(bool) which works, but the checkbox then is grayed-out and hardly readable
  2. I can react on a toggle signal and reset the state. But I would need a kind of flag to determine if the box is read-only and then reset the check state, means I need to create my own CheckBox class.
  3. setCheckable does not work either, it does not allow me to set a checked state at all:

        cb = this->ui->cb_RealWorld->isCheckable();
        this->ui->cb_RealWorld->setCheckable(true);
        this->ui->cb_RealWorld->setChecked(someValue);
        this->ui->cb_RealWorld->setCheckable(cb);
    

So the best thing I have is to use enable/disable and accept the grayed out style.

------- Edit -------

Following the stylesheet examples I was hoping I could set the style of a disabled checkbox like the one of an enabled. Failed so far to do so. More specific: Changing the icon like in the examples does not work for me, maybe because I am using Windows and the icons are not available under the path as in the examples.


PS: Related, but no answer here

Disabling a QCheckbox in a tricky way
Qt - How to disable QCheckBox while retaining checked state?

Upvotes: 27

Views: 13735

Answers (6)

buhtz
buhtz

Reputation: 12202

Because I need to have tooltips on a read-only checkbox I used this solution in my PyQt6 code. The key is to overwrite the nextCheckState() method. In my solution I used an empty nameless method.

cb = QCheckBox('foobar')
cb.setChecked(True)
cb.nextCheckState = lambda: None

Here you see a real life example of two checkboxes, the first is read-only and the second is a regular one.

enter image description here

Upvotes: -1

user3454027
user3454027

Reputation: 11

  1. The solution with disabling all mouse events brokes tooltips
    setAttribute(Qt::WA_TransparentForMouseEvents);
  1. The solution with stylesheet helps some, but does not respect the parent widget state:
    QCheckBox[enabled="false"]{ color: black }/* text color same as in enabled state */
    /* the images must be prepared in advance */
    QCheckBox::indicator:unchecked { image: url(:/unchecked.png); }
    QCheckBox::indicator:checked   { image: url(:/checked.png); }
  1. Proper way IMHO is subclassing:
    class ReadonlyCheckBox : public QCheckBox
    {
        Q_OBJECT
    public:
        explicit ReadonlyCheckBox(QWidget *parent = nullptr) : QCheckBox(parent)
        {
            setFocusPolicy(Qt::NoFocus);
        }
        explicit ReadonlyCheckBox(const QString &text, QWidget *parent = nullptr) : QCheckBox(text, parent)
        {
            setFocusPolicy(Qt::NoFocus);
        }
    protected:
        virtual void mousePressEvent(QMouseEvent *event) override
        {
            event->ignore();
        }
    };

Upvotes: 1

Tomas
Tomas

Reputation: 101

Inherit from QCheckBox and override nextCheckState method https://doc.qt.io/qt-5/qcheckbox.html#nextCheckState do the trick.

void ReadOnlyCheckBox::nextCheckState()
{

}

Upvotes: 2

sqr3bk
sqr3bk

Reputation: 11

On Windows, remember to #include "windows.h" and set flags as follows:

this->ui->cb_RealWorld->setWindowFlags(this->ui->cb_RealWorld->windowFlags() | Qt::WindowTransparentForInput);

Upvotes: 1

Silicomancer
Silicomancer

Reputation: 9176

This is Devopia's solution as a function:

void SetReadOnly(QCheckBox* checkBox, bool readOnly)
{
   checkBox->setAttribute(Qt::WA_TransparentForMouseEvents, readOnly);
   checkBox->setFocusPolicy(readOnly ? Qt::NoFocus : Qt::StrongFocus);
}

Upvotes: 13

Devopia
Devopia

Reputation: 670

Following the below my code:

this->ui->cb_RealWorld->setAttribute(Qt::WA_TransparentForMouseEvents);
this->ui->cb_RealWorld->setFocusPolicy(Qt::NoFocus);

Upvotes: 35

Related Questions