我是QGridLayout
,其中每个单元格都包含我自定义的自定义窗口小部件QFrameExtended
,如下所示:
在.h:
#ifndef QFRAMEEXTENDED_H
#define QFRAMEEXTENDED_H
#include <QObject>
#include <QFrame>
class QFrameExtended : public QFrame
{
Q_OBJECT
private:
public:
int id;
explicit QFrameExtended(QWidget *parent = 0);
signals:
void mousePressEvent(QMouseEvent *);
void mouseReleaseEvent(QMouseEvent *);
void pressed(QFrameExtended *);
void released(QFrameExtended *);
public slots:
void on_mouse_press();
void on_mouse_release();
};
#endif // QFRAMEEXTENDED_H
在.cpp:
#include "qframe_extended.h"
QFrameExtended::QFrameExtended(QWidget *parent) : QFrame(parent)
{
this->id = /* Imagine here there is a function to generate an id */ ;
connect( this, SIGNAL( mousePressEvent(QMouseEvent*) ), this, SLOT( on_mouse_press() ) );
connect( this, SIGNAL( mouseReleaseEvent(QMouseEvent*) ), this, SLOT( on_mouse_release() ) );
}
void QFrameExtended::on_mouse_press() {
emit pressed(this);
}
void QFrameExtended::on_mouse_release() {
emit released(this);
}
我的表单使用QGridLayout
小部件创建QFrameExtended
,并为每个小部件定义一个事件处理程序:
/* ... */
/* This snippet of code is inside a loop that is creating frame objects */
connect(frame, &QFrameExtended::pressed, this, &MyForm::on_mouse_press);
connect(frame, &QFrameExtended::released, this, &MyForm::on_mouse_release);
/* ... */
最后这些是事件处理程序:
void MyForm::on_mouse_press(QFrameExtended *frame) {
qDebug() << "Pressed here: " << frame->id << endl;
}
void MyForm::on_mouse_release(QFrameExtended *frame) {
qDebug() << "Released here: " << frame->id << endl;
}
当我单击一个单元格(即QFrameExtended小部件)而没有释放按钮时,我会在控制台上看到单元格的id。将鼠标移到另一个单元格后,当我释放按钮时,我会看到打印出第二个ID。
一个例子就是这样的输出:
按此处:1
发布于此:3
但实际情况是,当我在QFrameExtended上按下鼠标按钮时,他开始抓取所有鼠标事件,直到我释放按钮。这是预期的行为:
当在窗口小部件中按下鼠标按钮时,Qt会自动抓取鼠标;小部件将继续接收鼠标事件,直到释放最后一个鼠标按钮。
来自:http://doc.qt.io/qt-4.8/qmouseevent.html
如何更改此行为?如果你能给我一个例子,我真的很感激
答案 0 :(得分:0)
好的,我解决了问题。我试图扩展QGridLayout
,但布局不支持鼠标事件,因为我们不会继承QWidget
。所以,我扩展了包含布局的QWidget
。
在.h:
#ifndef QWIDGETEXTENDED_H
#define QWIDGETEXTENDED_H
#include <QWidget>
#include <QString>
#include <QMouseEvent>
#include "qframe_extended.h"
class QWidgetExtended : public QWidget
{
Q_OBJECT
public:
explicit QWidgetExtended(QWidget *parent = 0);
protected:
virtual void mousePressEvent(QMouseEvent *);
virtual void mouseReleaseEvent(QMouseEvent *);
signals:
void pressed(QFrameExtended *);
void released(QFrameExtended *);
};
#endif
在.cpp:
#include "qwidget_extended.h"
#include "qframe_extended.h"
QWidgetExtended::QWidgetExtended(QWidget *parent) : QWidget(parent)
{
}
void QWidgetExtended::mousePressEvent(QMouseEvent *event) {
QFrameExtended frame;
QWidget *widget = this->childAt(event->pos());
if (widget != NULL) {
QString widgetClassName(widget->metaObject()->className());
//I don't use explicitly the string because if one day someone changes the name of the class, the compiler will output an error
QString className(frame.metaObject()->className());
if (widgetClassName == className) {
emit pressed(dynamic_cast<QFrameExtended*> (widget));
}
}
}
void QWidgetExtended::mouseReleaseEvent(QMouseEvent *event) {
QFrameExtended frame;
QWidget *widget = this->childAt(event->pos());
if (widget != NULL) {
QString widgetClassName(widget->metaObject()->className());
//I don't use explicitly the string because if one day someone changes the name of the class, the compiler will output an error
QString className(frame.metaObject()->className());
if (widgetClassName == className) {
emit released(dynamic_cast<QFrameExtended*> (widget));
}
}
}