Solved QPushButton "pressed" signal emitting twice when moving mouse
-
Here is the minimal code to reproduce the issue.
- MainWindow.cpp ---------------------------------------
#include "MainWindow.h"
#include <QSignalMapper>
#include <QDebug>
#include <QMetaMethod>
#include <QMetaObject>#define NO_OF_ROWS 2
#define NO_OF_COLUMNS 2
#define NO_OF_BUTTONS 4MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
m_testObject(new TestObject(this))
{
setupUi();
connect(this, &MainWindow::buttonPressed, m_testObject, &TestObject::onButtonPressed, Qt::UniqueConnection);
connect(this, &MainWindow::F1Pressed, m_testObject, &TestObject::onF1Pressed);
connect(this, &MainWindow::F2Pressed, m_testObject, &TestObject::onF2Pressed);
connect(this, &MainWindow::F3Pressed, m_testObject, &TestObject::onF3Pressed);
connect(this, &MainWindow::F4Pressed, m_testObject, &TestObject::onF4Pressed);
}MainWindow::~MainWindow()
{
}void MainWindow::addButtonsToLayout(QGridLayout* gridLayout)
{
QSignalMapper *mapper = new QSignalMapper(this);for (int i = 0; i < NO_OF_BUTTONS; ++i) { QPushButton *button = new QPushButton(m_centralWidget); button->setObjectName(QString("pushButton_%1").arg(i+1)); button->setText(QString("F%1").arg(i+1)); mapper->setMapping(button, i+1); connect(button, SIGNAL(pressed()), mapper, SLOT(map()), Qt::QueuedConnection); gridLayout->addWidget(button, i / NO_OF_COLUMNS, i % NO_OF_COLUMNS, 1, 1); } connect(mapper, SIGNAL(mapped(int)), this, SLOT(onButtonClicked(int)));
}
void MainWindow::onButtonClicked(int i)
{
qDebug() << "Button Clicked = " << i;
QMetaObject::invokeMethod(this, QString("F%1Pressed").arg(i).toStdString().c_str(), Qt::QueuedConnection);
QMetaObject::invokeMethod(this, QString("buttonPressed").arg(i).toStdString().c_str(), Qt::QueuedConnection, Q_ARG(int, i));
//emit buttonPressed(i);
}void MainWindow::setUpMainLayout()
{
m_centralWidget = new QWidget(this);
m_centralWidget->setObjectName(QStringLiteral("centralWidget"));QGridLayout* gridLayout = new QGridLayout(m_centralWidget); gridLayout->setSpacing(6); gridLayout->setContentsMargins(11, 11, 11, 11); gridLayout->setObjectName(QStringLiteral("gridLayout")); addButtonsToLayout(gridLayout); setCentralWidget(m_centralWidget);
}
void MainWindow::setupUi()
{
if (objectName().isEmpty())
setObjectName(QStringLiteral("MainWindow"));resize(400, 300); setUpMainLayout(); retranslateUi(); QMetaObject::connectSlotsByName(this);
}
void MainWindow::retranslateUi()
{
setWindowTitle("MainWindow");
}- TestObject.cpp ----------------
#include "TestObject.h"
#include <QDebug>
#include <QWidget>
#include <TestThread.h>TestObject::TestObject(QObject *parent) : QObject(parent)
{
}void TestObject::onButtonPressed(int i)
{
qDebug() << Q_FUNC_INFO;QWidget *wid = new QWidget(); wid->setWindowFlag(Qt::Window); wid->setAttribute(Qt::WA_DeleteOnClose); wid->show();
}
void TestObject::onF1Pressed()
{
qDebug() << Q_FUNC_INFO;
}void TestObject::onF2Pressed()
{
qDebug() << Q_FUNC_INFO;
}void TestObject::onF3Pressed()
{
qDebug() << Q_FUNC_INFO;
}void TestObject::onF4Pressed()
{
qDebug() << Q_FUNC_INFO;
}The issue occurs when i press and move mouse on any of the Button. I get 2 Window.
-
Surprised. Which platform ?
Can you check with simple example like the follows ?
int main(int argc, char *argv[]) { QApplication a(argc, argv); QPushButton button("PressMe"); QObject::connect(&button,&QPushButton::pressed,[](){ qDebug() << " Call me" <<endl; }); button.show(); return a.exec(); }
-
@dheerendra On Windows. I have Qt 5.12.
A normal press works fine. Also if the slot connected to pressed signal doesn't open Widget then it works fine.
The issue only happens when I press a button then move mouse and then release. And in the slot i try to open a widget.
-
The issue only happens when I press a button then move mouse and then release.
Did the above issue happens with code which I gave you ?
-
@dheerendra No. As i said, happens only when a widget is shown.
-
This indicates that there must be some logic issue the way coding is done. Can you post your minimal working code somewhere ? I looked the code posted. We need to write header file etc on our own. So if you give us complete code somewhere in pastebin or somewhere we can look at the issue & suggest.
-
@dheerendra Please find minimal code at https://pastebin.com/SytA0BG1
Remember you need to press and move your mouse on a button ("F1" or any other).
-
@Maaz-Momin said in QPushButton "pressed" signal emitting twice when moving mouse:
Remember you need to press and move your mouse on a button ("F1" or any other).
Sure will remember :)
-
I found the reason for this topic. Sorry for updating it so late. The code inside QAbstractButton emits the pressed signal twice (One in MousePressEvent and Second in MoveMoveEvent).
Solution: Create a custom class inheriting QPushButton. Override mouseMoveEvent and do not pass it to QPushButton/QAbstractButton (Because in my case I don't do any operation on mouseMoveEvent so solution is good for my case)