QRadioButton reselect quickly and deselect again after enabling the radiobutton
-
Hello Everyone,
I bind some radio button to a check box with the following scenario:
1-when the check box is checked user can select one of radio buttons.
2-when the check box is unchecked all of radio buttons become disable and deselect radio buttons that previously was selected by user.Now if user checked the checkbox in order to re enabling the radio buttons you can see that the radio button will select for a moment and deselect again(That's weird) the following code make the scenario that I've explained :
void MainWindow::on_myCheckBox_clicked() { bool check=ui->myCheckBox->isChecked(); if(check) { /*Check*/ ui->radioButton->setAutoExclusive(true); ui->radioButton->setCheckable(true); ui->radioButton_2->setAutoExclusive(true); ui->radioButton_2->setCheckable(true); ui->radioButton_3->setAutoExclusive(true); ui->radioButton_3->setCheckable(true); ui->radioButton->setEnabled(true); ui->radioButton_2->setEnabled(true); ui->radioButton_3->setEnabled(true); } else { /*Unchek*/ ui->radioButton->setAutoExclusive(false); ui->radioButton->setChecked(false); ui->radioButton_2->setAutoExclusive(false); ui->radioButton_2->setChecked(false); ui->radioButton_3->setAutoExclusive(false); ui->radioButton_3->setChecked(false); ui->radioButton->setEnabled(false); ui->radioButton_2->setEnabled(false); ui->radioButton_3->setEnabled(false); } }
Why Qt does in this way and how to solve the problem?
I appreciate any idea. -
Hello Everyone,
I bind some radio button to a check box with the following scenario:
1-when the check box is checked user can select one of radio buttons.
2-when the check box is unchecked all of radio buttons become disable and deselect radio buttons that previously was selected by user.Now if user checked the checkbox in order to re enabling the radio buttons you can see that the radio button will select for a moment and deselect again(That's weird) the following code make the scenario that I've explained :
void MainWindow::on_myCheckBox_clicked() { bool check=ui->myCheckBox->isChecked(); if(check) { /*Check*/ ui->radioButton->setAutoExclusive(true); ui->radioButton->setCheckable(true); ui->radioButton_2->setAutoExclusive(true); ui->radioButton_2->setCheckable(true); ui->radioButton_3->setAutoExclusive(true); ui->radioButton_3->setCheckable(true); ui->radioButton->setEnabled(true); ui->radioButton_2->setEnabled(true); ui->radioButton_3->setEnabled(true); } else { /*Unchek*/ ui->radioButton->setAutoExclusive(false); ui->radioButton->setChecked(false); ui->radioButton_2->setAutoExclusive(false); ui->radioButton_2->setChecked(false); ui->radioButton_3->setAutoExclusive(false); ui->radioButton_3->setChecked(false); ui->radioButton->setEnabled(false); ui->radioButton_2->setEnabled(false); ui->radioButton_3->setEnabled(false); } }
Why Qt does in this way and how to solve the problem?
I appreciate any idea.Most likely you are running into a dependency issue. You better check how many times the slot routine is being called.
Not only checking the radio button with the mouse is going to trigger the routine. Also your application activities of checking and unchecking has the same effect. In addition it looks like you have all in a checkbox, which may create another level of dependencies. It is very easy to create also some infinite loops that way.
-
Most likely you are running into a dependency issue. You better check how many times the slot routine is being called.
Not only checking the radio button with the mouse is going to trigger the routine. Also your application activities of checking and unchecking has the same effect. In addition it looks like you have all in a checkbox, which may create another level of dependencies. It is very easy to create also some infinite loops that way.
-
Looking at your code it seems that your sequence of calls will probably result in not just one, but sometimes even two selections, as you deselect each radio button in the group. That's to say:
ui->radioButton->setAutoExclusive(false); ui->radioButton->setChecked(false); // OK, so now if radioButton was checked, the next one in the sequence gets checked. ui->radioButton_2->setAutoExclusive(false); ui->radioButton_2->setChecked(false); // Now, if radioButton_2 was checked, radioButton_3 gets checked ui->radioButton_3->setAutoExclusive(false); ui->radioButton_3->setChecked(false);
Do you really need to do that first set of calls (the
setAutoExclusive(false)
andsetChecked(false)
? In most cases I've run intosetEnabled(false)
by itself gets me the effect I'm after. -
Looking at your code it seems that your sequence of calls will probably result in not just one, but sometimes even two selections, as you deselect each radio button in the group. That's to say:
ui->radioButton->setAutoExclusive(false); ui->radioButton->setChecked(false); // OK, so now if radioButton was checked, the next one in the sequence gets checked. ui->radioButton_2->setAutoExclusive(false); ui->radioButton_2->setChecked(false); // Now, if radioButton_2 was checked, radioButton_3 gets checked ui->radioButton_3->setAutoExclusive(false); ui->radioButton_3->setChecked(false);
Do you really need to do that first set of calls (the
setAutoExclusive(false)
andsetChecked(false)
? In most cases I've run intosetEnabled(false)
by itself gets me the effect I'm after.Dear @Chris-Hennes,
Yes I want to clear all of the radio buttons and then make them disable.Actually it seems a QT bug I really don't know!
My problem is reappearing of selected radio button to select state for a moment and again it disappears quickly after enabling radio buttons that is odd behavior. -
How about using QButtonGroup.
You add your 3 buttons to it and add another invisible one. check the invisible button when all the others should be unchecked -
Dear @Chris-Hennes,
Yes I want to clear all of the radio buttons and then make them disable.Actually it seems a QT bug I really don't know!
My problem is reappearing of selected radio button to select state for a moment and again it disappears quickly after enabling radio buttons that is odd behavior.@Alien said in QRadioButton reselect quickly and deselect again after enabling the radiobutton:
Actually it seems a QT bug I really don't know!
I'd disagree - the whole point of a radio button is that one button in the group must be selected. So every time you try to deselect one, the next one gets selected. I think @VRonin 's suggestion is the best way, if you can't just hide those radios.
-
Dear @VRonin and @Chris-Hennes ,
Might be I couldn't say the problem clearly I use the QButtonGroup now but the problem still exist so could you please run my code and say what you see?Header:
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include <QButtonGroup> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_checkBox_clicked(); private: Ui::MainWindow *ui; QButtonGroup *m_btnGroup; }; #endif // MAINWINDOW_H
source file :
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); m_btnGroup = new QButtonGroup(); m_btnGroup->addButton(ui->radioButton); m_btnGroup->addButton(ui->radioButton_2); ui->checkBox->setChecked(true); } MainWindow::~MainWindow() { m_btnGroup->deleteLater(); delete ui; } void MainWindow::on_checkBox_clicked() { bool check = ui->checkBox->isChecked(); if(check) { m_btnGroup->setExclusive(true); ui->radioButton->setEnabled(true); ui->radioButton_2->setEnabled(true); } else { m_btnGroup->setExclusive(false); ui->radioButton->setChecked(false); ui->radioButton_2->setChecked(false); ui->radioButton->setEnabled(false); ui->radioButton_2->setEnabled(false); } }
Just create project and put one check box and two radio buttons on ui file then try to select one radio button and uncheck the checkbox now check it again while you are watching the radio buttons(what you see).
QT SDK = 5.8.0 on windows by mingw compiler set.
I appreciate your help. -
This post is deleted!
-
OK, I see what you are getting at -- it's almost like Qt is caching the actual drawing of the checked, active radio button and using that image briefly before updating it to the correct unchecked state. I haven't chased through the signal propagation, but I wonder if hooking into the repaint event of those widgets will give you any information about why this is happening. No amount of fiddling with the radio button grouping or the order of checking/enabling/etc. seems to resolve it. I even tried using a one-shot timer to push the updating of the widget to later in the event queue, which had no effect.
-
OK, I see what you are getting at -- it's almost like Qt is caching the actual drawing of the checked, active radio button and using that image briefly before updating it to the correct unchecked state. I haven't chased through the signal propagation, but I wonder if hooking into the repaint event of those widgets will give you any information about why this is happening. No amount of fiddling with the radio button grouping or the order of checking/enabling/etc. seems to resolve it. I even tried using a one-shot timer to push the updating of the widget to later in the event queue, which had no effect.
@Chris-Hennes That's right. So what should I do to get rid of that?
-
Hi, this "ghosting" occurs I think because Qt doesn't paint/render the buttons until you exit on_checkBox_clicked().
What you can try is to stage the updates: first do ->setChecked(false) and let Qt paint/render the screen, and then do setEnabled(false), like this:
m_btnGroup->setExclusive(false); ui->radioButton->setChecked(false); ui->radioButton_2->setChecked(false); qApp->processEvents(); // <-- forces screen update ui->radioButton->setEnabled(false); ui->radioButton_2->setEnabled(false);
qApp->processEvents() is a bit perilous though, you can easily fall into recursive loops, perhaps a better approach would be to "include timer.h" and:
m_btnGroup->setExclusive(false); ui->radioButton->setChecked(false); ui->radioButton_2->setChecked(false); QTimer::singleShot(10,[this] { ui->radioButton->setEnabled(false); ui->radioButton_2->setEnabled(false); });
Either way that "ghosting" should go away :-)
-
Hi, this "ghosting" occurs I think because Qt doesn't paint/render the buttons until you exit on_checkBox_clicked().
What you can try is to stage the updates: first do ->setChecked(false) and let Qt paint/render the screen, and then do setEnabled(false), like this:
m_btnGroup->setExclusive(false); ui->radioButton->setChecked(false); ui->radioButton_2->setChecked(false); qApp->processEvents(); // <-- forces screen update ui->radioButton->setEnabled(false); ui->radioButton_2->setEnabled(false);
qApp->processEvents() is a bit perilous though, you can easily fall into recursive loops, perhaps a better approach would be to "include timer.h" and:
m_btnGroup->setExclusive(false); ui->radioButton->setChecked(false); ui->radioButton_2->setChecked(false); QTimer::singleShot(10,[this] { ui->radioButton->setEnabled(false); ui->radioButton_2->setEnabled(false); });
Either way that "ghosting" should go away :-)
Dear @hskoglund ,
Thank you so much that is work for me.