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?
问题:
回答1:
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();
}
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!
回答2:
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.
回答3:
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.