我想从鼠标的右键保持所有左键,在QPushButton上实现鼠标左键的所有功能(如clicked(),pressed(),release(),setAutoRepeat())功能完好。以下是重新实现eventFilter的代码,它没有给出理想的结果。
class object : public boost::enable_shared_from_this<object> {
public:
object()
: service(new boost::asio::io_service),
work(new boost::asio::io_service::work(*service)),
strand(*service),
value(0) {}
void workerThread() {
service->run();
}
void run() {
func_int = strand.wrap(boost::bind(&object::handler_int, shared_from_this(), _1));
func_void = strand.wrap(boost::bind(&object::handler_void, shared_from_this()));
std::thread thread(boost::bind(&object::workerThread, this));
func_int(1);
func_int(1);
func_void();
func_void(); // Will crash due to shared_ptr being NULL, hence "value" cannot be accessed in handler_void
thread.join();
}
void handler_int(int parameter) {
cout << "handler_int: " << value << endl;
}
void handler_void() {
cout << "handler_void: " << value << endl;
}
boost::shared_ptr<boost::asio::io_service> service;
boost::shared_ptr<boost::asio::io_service::work> work;
boost::asio::strand strand;
std::function<void(int)> func_int;
std::function<void(void)> func_void;
int value;
};
int main(int argc, char *argv[]) {
boost::shared_ptr<object> obj(new object());
obj->run();
return 0;
}
任何人都可以帮忙吗?提前谢谢。
答案 0 :(得分:2)
您不应该为此使用事件过滤器。子类QPushButton
并实现您自己的右键单击处理。这是一个工作示例(我没有彻底测试它,因此可能存在一些问题):
#include <QApplication>
#include <QPushButton>
#include <QMouseEvent>
#include <QLayout>
#include <QDebug>
class CustomButton : public QPushButton
{
Q_OBJECT
public:
explicit CustomButton(QWidget *parent = 0) : QPushButton(parent){}
protected:
void mousePressEvent(QMouseEvent *e)
{
if(e->button() == Qt::RightButton && hitButton(e->pos()))
{
setDown(true);
emit pressed();
}
QPushButton::mousePressEvent(e);
}
void mouseMoveEvent(QMouseEvent *e)
{
if(e->buttons() & Qt::RightButton)
{
if(hitButton(e->pos()) != isDown())
setDown(!isDown());
}
QPushButton::mouseMoveEvent(e);
}
void mouseReleaseEvent(QMouseEvent *e)
{
if(e->button() == Qt::RightButton)
{
setDown(false);
if(hitButton(e->pos()))
click();
}
QPushButton::mouseReleaseEvent(e);
}
};
void buttonClicked()
{
qDebug() << "CLICKED";
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWidget w;
w.resize(500,500);
w.setLayout(new QVBoxLayout);
CustomButton button;
button.setAutoRepeat(true);
QObject::connect(&button, &CustomButton::clicked, &buttonClicked);
w.layout()->addWidget(&button);
w.show();
return a.exec();
}
#include "main.moc"
如果要区分右键单击和左键单击,请参阅source code for QAbstractButton::click
,并实现自己的右键单击。
答案 1 :(得分:0)
您可以在事件过滤器中实现该功能,并将其安装在您想要可右键单击的按钮上。
// https://github.com/KubaO/stackoverflown/tree/master/questions/right-to-left-event-39220180
#include <QtWidgets>
class RightToLeftClick : public QObject {
bool eventFilter(QObject *watched, QEvent *event) {
if (event->type() == QEvent::MouseButtonDblClick ||
event->type() == QEvent::MouseButtonPress ||
event->type() == QEvent::MouseButtonRelease) {
auto ev = static_cast<QMouseEvent*>(event);
if (ev->button() == Qt::RightButton) {
auto buttons = ev->buttons();
if (buttons & Qt::RightButton) {
buttons ^= Qt::RightButton;
buttons |= Qt::LeftButton;
}
QMouseEvent lev{ev->type(),
ev->localPos(),
ev->windowPos(),
ev->screenPos(),
Qt::LeftButton,
buttons,
ev->modifiers(),
ev->source()};
Q_ASSERT(! (lev.buttons() & Qt::RightButton));
QCoreApplication::sendEvent(watched, &lev);
return true;
}
}
return QObject::eventFilter(watched, event);
}
public:
explicit RightToLeftClick(QObject * parent = nullptr) : QObject{parent} {
addTo(parent);
}
void addTo(QObject * obj) {
if (obj) obj->installEventFilter(this);
}
};
以下是如何使用它:
int main(int argc, char ** argv) {
QApplication app{argc, argv};
QWidget ui;
QVBoxLayout layout{&ui};
QPushButton button1{"Left Click Me"};
QPushButton button2{"Right Click Me"};
layout.addWidget(&button1);
layout.addWidget(&button2);
ui.show();
RightToLeftClick rtl{&button2};
return app.exec();
}