I'm using Qt Creator to create a gui for a mineseeper game. How can I know a QpushButton clicked with rightclick? for flag in the game. In other word, which signal used for rightclick?
-
You'll probably need to override `event()` and emit the signal yourself. – rainer Mar 27 '13 at 12:15
-
1Why'd any one -1 this question?? Yes, there could have been more efforts, but the question is a good one. Thanks to Muhammad for a good answer. – zeFree Apr 09 '13 at 22:44
4 Answers
Create your own button with filter at mousePressEvent slot.
qrightclickbutton.h
#ifndef QRIGHTCLICKBUTTON_H
#define QRIGHTCLICKBUTTON_H
#include <QPushButton>
#include <QMouseEvent>
class QRightClickButton : public QPushButton
{
Q_OBJECT
public:
explicit QRightClickButton(QWidget *parent = 0);
private slots:
void mousePressEvent(QMouseEvent *e);
signals:
void rightClicked();
public slots:
};
#endif // QRIGHTCLICKBUTTON_H
qrightclickbutton.cpp
#include "qrightclickbutton.h"
QRightClickButton::QRightClickButton(QWidget *parent) :
QPushButton(parent)
{
}
void QRightClickButton::mousePressEvent(QMouseEvent *e)
{
if(e->button()==Qt::RightButton)
emit rightClicked();
mousePressEvent(QMouseEvent *e)
}
Now connect like this
QRightClickButton *button = new QRightClickButton(this);
ui->gridLayout->addWidget(button);
connect(button, SIGNAL(rightClicked()), this, SLOT(onRightClicked()));
Create a slot in MainWindow.cpp.
void MainWindow::onRightClicked()
{
qDebug() << "User right clicked me";
}
It works for me!

- 619
- 5
- 14
-
2If anyone would like to connect() both to the generic clicked() signal and custom rightClicked() signal - it is necessary to call `QPushButton::mousePressEvent(e);` in the end of overridden `mousePressEvent(QMouseEvent *e)` – Krzysiek Apr 24 '16 at 15:51
I think QPushButton is internally implemented to listen to left mouse clicks only. But you can easily extend QPushButton and re-implement let's say the mouse release event and do your thing if the right mouse button was pressed, e.g. emit a custom rightClicked()
signal for example:
signals:
void rightClicked();
protected:
void mouseReleaseEvent(QMouseEvent *e) {
if (e->button() == Qt::RightButton) emit rightClicked();
else if (e->button() == Qt::LeftButton) emit clicked();
}
... or you can create an overload of the clicked signal that forwards the mouseEvent pointer so you can do the same check outside of the button.
signals:
void clicked(QMouseEvent *);
protected:
void mouseReleaseEvent(QMouseEvent *e) {
emit clicked(e);
}
Then you do the check in the slot you connect the button's clicked(QMouseEvent *)
signal to and proceed accordingly.

- 47,916
- 17
- 112
- 190
-
I'm using `QPushButton` and there is no `button()` in that. what should I do? – Khosi Mar 27 '13 at 12:40
-
-
so I don't know how can I use `mouseReleaseEvent`. why you call `rightClicked()` in `mouseReleaseEvent` ? – Khosi Mar 27 '13 at 13:01
-
@KhoC - because the `clicked` event occurs when you press and then release the button. This way you get the default behavior - when you click a button but move the mouse out of it before you release - you don't get a click. You can customize that according to your needs, you can also use the mousePressEvent if you like. – dtech Mar 27 '13 at 13:07
-
Why not calling the parent's `mouseReleaseEvent()` instead of emitting `clicked()` manually here? – eepp Aug 22 '15 at 07:01
I just wrote this little helper adapter to make any existing button right-clickable with no need to subclass it:
class CRightClickEnabler : public QObject
{
public:
CRightClickEnabler(QAbstractButton * button): QObject(button), _button(button) {
button->installEventFilter(this);
};
protected:
inline bool eventFilter(QObject *watched, QEvent *event) override {
if (event->type() == QEvent::MouseButtonPress)
{
auto mouseEvent = (QMouseEvent*)event;
if (mouseEvent->button() == Qt::RightButton)
_button->click();
}
return false;
}
private:
QAbstractButton* _button;
};
Usage:
connect(ui->pushButton, &QPushButton::clicked, [](){qDebug() << "Button clicked";});
new CRightClickEnabler(ui->pushButton);
From now on, the clicked
signal will be triggered by the right click as well as left click. There's no need to delete this object - it uses ui->pushButton
as parent and will be auto-deleted by Qt when the parent is destroyed.
Obviously, you can write 2 lines of code (literally) to declare a new signal here and emit that signal upon right click instead of clicked
, if desired.

- 32,368
- 48
- 194
- 335
-
This code is great, because i had some serious issues getting subclassing to work (qt noob here though). Just want to point out something important, this will be flaky if you right click the object too fast. You just have to also handle it for `QEvent::MouseButtonDblClick`! Actually I'd probably also say it should just be changed to `QEvent::MouseButtonRelease` since thats when click runs anyway. not on press. – Steven Lu May 14 '21 at 00:14
-
@StevenLu, that's a good and sensible suggestion, thanks for pointing it out! And I'm glad to hear my little code snippet helped. – Violet Giraffe May 14 '21 at 21:09
I'd like to suggest this option as well, without need for event filter/other stuffs...
self.button.released.connect(self.doStuff)
self.button.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
self.button.customContextMenuRequested.connect(partial(self.doStuff, False))
def doStuff(self,state=True,p=QPoint()):
print("True for left, False for right!",state)

- 960
- 13
- 36