Reputation: 89
When I have a QCheckBox with tristate set true, it does not repaint itself when transitioning from Qt:PartiallyChecked to setChecked(true) programatically.
A minimal example built in QDesigner places a QCheckBox and QPushButton on the central widget of the default MainWindow. The QCheckBox is default configured except tristate is checked. In code, the ui checkBox is set to Qt::PartiallyChecked in the constructor, and an on_pushButton_clicked() function calls ui->checkBox->setChecked( true );
Expected behavior: when pushButton is clicked, checkBox should change from partially checked to checked appearance.
Observed behavior: checkBox appearance does not change until moused over.
Note: it's even worse when the checkbox has been restyled to be used as a tri-state indicator and is not enabled for user input... the disabled checkbox doesn't repaint on mouseover then.
I discovered this behavior in Ubuntu 18.04 default using the native 5.9.5 Qt libraries running in release mode, but it is also reproducible in 5.14.2 and many other library versions.
The sample code below is 99% the default Qt Widgets application with modification as described above.
The only workaround I have found so far is to repaint the QCheckBox widget anytime its state is changed... not great, but at least it works.
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{ ui->setupUi(this);
ui->checkBox->setCheckState( Qt::PartiallyChecked );
}
MainWindow::~MainWindow()
{ delete ui; }
void MainWindow::on_pushButton_clicked()
{ ui->checkBox->setChecked( true );
// Uncomment the repaint() for a kludgey fix
// ui->checkBox->repaint();
}
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
public slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
main.cpp:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>173</width>
<height>98</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QCheckBox" name="checkBox">
<property name="geometry">
<rect>
<x>40</x>
<y>10</y>
<width>92</width>
<height>23</height>
</rect>
</property>
<property name="text">
<string>CheckBox</string>
</property>
<property name="tristate">
<bool>true</bool>
</property>
</widget>
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>40</x>
<y>50</y>
<width>89</width>
<height>25</height>
</rect>
</property>
<property name="text">
<string>PushButton</string>
</property>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>
Tristate.pro:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
Upvotes: 0
Views: 392
Reputation: 89
Best patch I know so far is to repaint the QCheckBox whenever its state is changed.
Upvotes: 0