Я не уверен, что на 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
.
- (лучше :) Поскольку вы уже используете Qt, создайте сигнал
MainWidget::SignalMouseMove(QPoint p)
и слот MainWidget::MouseMovedSlot(QPoint p)
. - При инициализации общего родительского виджета вы подключаете слоты обоих виджетов к сигналу каждого виджета (см. Ниже).
- В MainWidget
mouseMoveEvent()
do 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 прямоугольник и передать его каждому другому виджету, чтобы показать его (с соответствующей геометрией), потому что это позволит мне перемещаться, а изменение размера будет отражаться на всех виджетах.
Отображение одного и того же экземпляра виджета в двух разных родительских виджетах может возможно, но определенно выглядит как кладж, а не как Qt.
Вы должны взглянуть на Qt's модель-представление-программирование , потому что это, по сути, то, чего вы хотите достичь:
- Отображение одной модели в двух видах.
- Обновление обоих видов при любом изменении модели.
Поскольку реализация QAbstractItemModel
немного избыточна для этого, вот несколько альтернатив:
- Использование Graphics View Framework Qt :Отобразите то же самое
QGraphicsScene
за две QGraphicsView
с и поместите в сцену немного QGraphicsRectItem
. - Используйте поддержку параметров Qt для полуавтоматического связывания данных.
- Сверните свое, этоне так уж сложно:
- По сути, вы должны отделить логику view от логики model , например,
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();
}