我有一个继承MainWidget
的基类QOpenGLWidget
。 MainWidget
有2个子类ColorWidget
和BWWidget
。我希望同步在两个子窗口小部件之间绘制一个矩形,即当我开始在ColorWidget
上绘制一个形状时,该形状应显示在BWWidget
上。我已覆盖mouseMoveEvent
基类来绘制矩形。
void MainWidget::mouseMoveEvent(QMouseEvent* event)
{
if(m_mousePressed && event->type() == QEvent::MouseMove)
{
// check some conditions
if (/*conditions*/)
{
m_activeItem.reset(new Rectangle(this));
m_activeItem->show();
}
}
}
我可以单独在子类上绘制矩形。但我希望它们能够被同时绘制。我试图为两个子类覆盖mouseMoveEvent
,但似乎从子类调用MainWidget::mouseMoveEvent()
将导致无限循环和崩溃。
就我而言,ColorWidget
和BWWidget
的父级是QDockWidget
,我的Rectangle
级继承QLabel
。
我不确定如何实现这一点。
答案 0 :(得分:0)
我不确定我100%理解你在这里问的是什么(主要是因为你没有提供一个最小的可编辑的例子),这就是我所理解的:
class ColorWidget : public MainWidget
class BWWidget : public MainWidget
class MainWidget : public QOpenGLWidget
mouseMoveEvent()
时,两者都应显示一些内容。如果这就是你所拥有的,那么这些是你的选择:
MainWidget::DrawMouseMoveRectangle(QPoint pos)
。
QPointer<MainWidget> pOther
)。
mouseMoveEvent()
并致电DrawMouseMoveRectangle(QPoint pos)
this
和pOther
。MainWidget::SignalMouseMove(QPoint p)
和广告位MainWidget::MouseMovedSlot(QPoint p)
。
mouseMoveEvent()
做emit SignalMouseMove(evt->pos)
*
如何建立联系:
bool ok = true;
ok = ok && connect(w1, &MainWidget::SignalMouseMove, w1, &MainWidget::MouseMovedSlot);
ok = ok && connect(w1, &MainWidget::SignalMouseMove, w2, &MainWidget::MouseMovedSlot);
ok = ok && connect(w2, &MainWidget::SignalMouseMove, w1, &MainWidget::MouseMovedSlot);
ok = ok && connect(w2, &MainWidget::SignalMouseMove, w2, &MainWidget::MouseMovedSlot);
Q_ASSERT(ok);
修改强>
回答你的评论:
我想要的是我应该能够绘制1个矩形并将其传递给其他每个小部件以显示它(具有适当的几何体),因为它将使我移动和调整大小将反映在所有小部件上。
在两个不同的父窗口小部件中显示窗口小部件的相同实例可能,但肯定感觉像是一个kludge,而不是Qt的设计方式。
你应该看看Qt's model-view-programming,因为这基本上是你想要实现的目标:
因为实施QAbstractItemModel
对此有点矫枉过正,所以有以下几种选择:
QGraphicsScene
中显示相同的QGraphicsView
,并将一些QGraphicsRectItem
放入场景中。RectangleView
和RectangleModel
。编辑2:使用共享QGraphicsRectItem的非常简单示例
// this is a minimal compilable example of two views sharing the same model, with automatic update on mouse events
#include <QApplication>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QGraphicsRectItem>
#include <QMouseEvent>
#include <QHBoxLayout>
class TestWidget : public QWidget
{
//Q_OBJECT // Not neccessary here because we don't use and don't need moc for this example. -> Don't try this at home!
public:
TestWidget() : QWidget(Q_NULLPTR),
lt(new QHBoxLayout(this)),
v1(new QGraphicsView(this)),
v2(new QGraphicsView(this)),
s(new QGraphicsScene(this)),
r(Q_NULLPTR)
{
// initialization
r = s->addRect(0, 0, 10, 10, QPen(Qt::red), Qt::yellow);
lt->addWidget(v1);
lt->addWidget(v2);
// sharing the same model:
v1->setScene(s);
v2->setScene(s);
// in reality, you need to share QGraphicsRectItem *r, too.
// (it would actually be sufficient to share *r only)
// very simple mouse interaction:
v1->viewport()->installEventFilter(this);
v1->viewport()->setMouseTracking(true);
v2->viewport()->installEventFilter(this);
v2->viewport()->setMouseTracking(true);
}
bool eventFilter(QObject *o, QEvent *evt) Q_DECL_OVERRIDE
{
QGraphicsView *gv = Q_NULLPTR;
if(o == v1->viewport())
{
gv = v1;
}
else if(o == v2->viewport())
{
gv = v2;
}
if(gv != Q_NULLPTR)
{
QPointF p;
switch(evt->type())
{
case QEvent::MouseMove:
p = static_cast<QMouseEvent*>(evt)->pos();
evt->accept();
break;
default:
break;
}
if(p != QPoint())
{
// do something different depending on interacting view - just for demonstration
if(gv == v1)
{
r->setRect(QRectF(p, r->rect().bottomRight()));
}
else
{
r->setRect(QRectF(r->rect().topLeft(), p));
}
}
}
return QWidget::eventFilter(o, evt);
}
private:
QHBoxLayout *lt;
QGraphicsView *v1;
QGraphicsView *v2;
QGraphicsScene *s;
QGraphicsRectItem *r;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
TestWidget w;
w.show();
return a.exec();
}