3 Attachment(s)
QPushButton Requires Two Clicks (Not Always)
MacOS 10.15.16
QT version 5.15
Creator 4.12.4
Hey everyone,
I am having a really annoying issue with buttons in my project. I made a very simple project that can replicate the bug.
What happens is when I click the remove button to remove an item, the next time I click the add button will always require me to click it twice. It does not register the first time.
I narrowed down the issue but have no idea how to fix it.
The problem is from layouts I think. The first screenshot shows it working works fine, does not require two clicks. But when I add the new button in the same layout as the remove button, that is when it happens.
Attachment 13524
Attachment 13525
Here are the only lines of code in my project
void MainWindow::on_removeItemButton_clicked()
{
ui->listWidget->takeItem(ui->listWidget->currentRow());
}
void MainWindow::on_addItemButton_clicked()
{
ui->listWidget->addItem("test");
}
I noticed that this happens with many things I try to do. Here is an instance where if I put everything inside a Tab Widget, the first time running the app will require two clicks on any of those buttons.
Clicking on an itemList item however works fine.
Attachment 13526
The issue only applies to buttons. Nothing else is being affected by this.
Any ideas?
Re: QPushButton Requires Two Clicks (Not Always)
Quote:
Here are the only lines of code in my project
Wow, you have an entire application that runs with only two methods of one line each? No header files, no main.cpp, no MainWindow constructor? Amazing.
Showing screenshots of Qt Designer in meaningless. All it shows is that you've specified a UI file for your project. The problem is almost certainly not in the layout of your GUI, it is in how you are connecting the signals and slots of the various UI components and what you are doing in those slots.
1 Attachment(s)
Re: QPushButton Requires Two Clicks (Not Always)
Quote:
Originally Posted by
d_stranz
Wow, you have an entire application that runs with only two methods of one line each? No header files, no main.cpp, no MainWindow constructor? Amazing.
Showing screenshots of Qt Designer in meaningless. All it shows is that you've specified a UI file for your project. The problem is almost certainly not in the layout of your GUI, it is in how you are connecting the signals and slots of the various UI components and what you are doing in those slots.
Whatever comes with a default new project is all that is in the rest of the code. The only thing I did was add a slot for the buttons like I said. Didn't think they would be important but here they are. If this is a default feature that's pretty weird lol.
It seems that what ever button is in the position of the remove button will be affected. If i swapped the add with remove, the remove button will be the one requiring two clicks after the add button is clicked. My guess about it being the layout is because of this reason. It affects that specific position in the layout.
Here is the project, I'm curious if it happens to anyone else running it.
Attachment 13527
Quote:
#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();
private slots:
void on_removeItemButton_clicked();
void on_addItemButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
Quote:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
Quote:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_removeItemButton_clicked()
{
ui->listWidget->takeItem(ui->listWidget->currentRow());
}
void MainWindow::on_addItemButton_clicked()
{
ui->listWidget->addItem("test");
}
Quote:
<?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>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="addItemButton">
<property name="text">
<string>Add Item</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="3" column="0">
<layout class="QVBoxLayout" name="verticalLayout"/>
</item>
<item row="0" column="0">
<widget class="QListWidget" name="listWidget">
<item>
<property name="text">
<string>New Item</string>
</property>
</item>
<item>
<property name="text">
<string>New Item</string>
</property>
</item>
<item>
<property name="text">
<string>New Item</string>
</property>
</item>
<item>
<property name="text">
<string>New Item</string>
</property>
</item>
<item>
<property name="text">
<string>New Item</string>
</property>
</item>
<item>
<property name="text">
<string>New Item</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="removeItemButton">
<property name="text">
<string>Remove Item</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
Re: QPushButton Requires Two Clicks (Not Always)
Not sure why the site is not allowing me to edit my post but I forgot to mention that even if I don't touch the code at all. If I don't add slots to the buttons or anything. It still happens. I can still see the remove button only showing that it's clicked on the second attempt.
Re: QPushButton Requires Two Clicks (Not Always)
For one thing, you aren't doing any error checking at all in your slots. You don't check the value of "currentRow()" and I would bet you real money that the first time you click, it has the value -1 because there is no current item. If you run your code in a debugger and set a breakpoint inside the on_removeItemButton_clicked() slot I am certain that you will see it gets called every time you click the button.
Because you have slots named "on_<buttonName>_clicked()", Qt's MOC automatically connects those slots to the corresponding buttons' "clicked()" signals. If somewhere in your code you also connect the button signal and your slot manually, then the slot will be called twice for every click. Most developers have learned to not let this automatic connection happen by naming their slots to something other than "on_<buttonName>_clicked()" because at some point everyone makes the mistake of having double connections which lead to all sorts of behavior that is hard to debug.
Your call to takeItem() creates a memory leak. takeItem() returns a pointer to the QListWidgetItem instance in that row, and you are responsible for deleting it.
Your UI file has an empty vertical layout at the bottom. I am guessing that what you really want is to put your whole central widget inside this layout.
1 Attachment(s)
Re: QPushButton Requires Two Clicks (Not Always)
Quote:
Originally Posted by
d_stranz
For one thing, you aren't doing any error checking at all in your slots. You don't check the value of "currentRow()" and I would bet you real money that the first time you click, it has the value -1 because there is no current item. If you run your code in a debugger and set a breakpoint inside the on_removeItemButton_clicked() slot I am certain that you will see it gets called every time you click the button.
Because you have slots named "on_<buttonName>_clicked()", Qt's MOC automatically connects those slots to the corresponding buttons' "clicked()" signals. If somewhere in your code you also connect the button signal and your slot manually, then the slot will be called twice for every click. Most developers have learned to not let this automatic connection happen by naming their slots to something other than "on_<buttonName>_clicked()" because at some point everyone makes the mistake of having double connections which lead to all sorts of behavior that is hard to debug.
Your call to takeItem() creates a memory leak. takeItem() returns a pointer to the QListWidgetItem instance in that row, and you are responsible for deleting it.
Your UI file has an empty vertical layout at the bottom. I am guessing that what you really want is to put your whole central widget inside this layout.
Your responses are about the slots. It happens if I don't touch the code at all so I am sure the slots are not causing the issue. The central widget cant be moved, thats the main grid. I took out the extra vertical layout but it still happens. The only difference now is it happens after clicking the button next to the remove button and then back to the add. No slots in any of them. They are just blank buttons. I am just watching the color of the button when clicking. And just to get your mind off the slots i commented them out too.
What else can it be? It happens more and more, the more widgets and layouts I start adding. But this example is pretty darn simple, this shouldn't be happening at all.
EDIT: To make it even more simple. I took out the listview widget. So now it's just literally 3 buttons inside 2 different horizontal layouts. It still happens.
Code:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
{
Q_OBJECT
public:
MainWindow
(QWidget *parent
= nullptr
);
~MainWindow();
private slots:
//void on_removeItemButton_clicked();
//void on_addItemButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
Code:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow
::MainWindow(QWidget *parent
) , ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
//void MainWindow::on_removeItemButton_clicked()
//{
// ui->listWidget->takeItem(ui->listWidget->currentRow());
//}
//void MainWindow::on_addItemButton_clicked()
//{
// ui->listWidget->addItem("test");
//}
Code:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
MainWindow w;
w.show();
return a.exec();
}
Code:
<?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>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="addItemButton">
<property name="text">
<string>Add Item</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="removeItemButton">
<property name="text">
<string>Remove Item</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>
Updated project file
Attachment 13529
Re: QPushButton Requires Two Clicks (Not Always)
If you have commented out all of the slots that are connected to your buttons, then how can you tell that it takes two clicks on any button to get a response? What exactly are you doing to determine that?
Re: QPushButton Requires Two Clicks (Not Always)
Quote:
Originally Posted by
d_stranz
If you have commented out all of the slots that are connected to your buttons, then how can you tell that it takes two clicks on any button to get a response? What exactly are you doing to determine that?
When you click them they turn blue for a second or until you let go of the mouse. Does not happen on the first click when the problem arises. Also can't be a coincidence that both the click animation and slot are not getting triggered at the same time. It's def the button not receiving the click. I also could just add the slot back with just print statements. Same thing. Does not show click animation or call the function.
Re: QPushButton Requires Two Clicks (Not Always)
Yes, I have this problem too, if i put the btn to layout, i must clicked twitce; if don't use QVBoxLayout it's work
But, If i set tabWidget is documentMode, It is work.
my system is OSX 10.15.6, Qt: 5.15
Quote:
#include "preferencewidget.h"
#include "ui_preferencewidget.h"
#include <QTabWidget>
#include <QPushButton>
#include <QDebug>
#include <QLayout>
#include <QVBoxLayout>
PreferenceWidget::PreferenceWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::PreferenceWidget)
{
ui->setupUi(this);
QTabWidget *tab = new QTabWidget(this);
QWidget *browser_tab = new QWidget;
QWidget *users_tab = new QWidget;
tab->addTab(browser_tab, "Browser");
tab->addTab(users_tab, "Users");
tab->setGeometry(20, 20, 300, 250);
QPushButton *btn = new QPushButton("Btn1");
btn->setGeometry(10, 30, 100, 40);
btn->setParent(users_tab);
QVBoxLayout *vl = new QVBoxLayout(users_tab);
vl->addWidget(btn);
users_tab->setLayout(vl);
connect(btn, SIGNAL(clicked()), this, SLOT(clickedAlert()));
}
PreferenceWidget::~PreferenceWidget()
{
delete ui;
}
void PreferenceWidget::clickedAlert()
{
qDebug() << "Clicked";
}