如何将 QMainWindow 鼠标点击位置传递给 QGraphicsView
Posted
技术标签:
【中文标题】如何将 QMainWindow 鼠标点击位置传递给 QGraphicsView【英文标题】:How to Pass QMainWindow mouse clicked position to QGraphicsView 【发布时间】:2016-09-06 14:49:52 【问题描述】:我有一个这样的显示窗口:
上面的显示小部件是QGraphicsView
小部件(它们在QGridLayout
中),我想要实现的是:
当用户单击MainWindow
时,我想抓住该单击位置并确定哪个QGraphicsView
小部件包含该位置并将所选QGraphicsView
小部件的边框设置为绿色。并且一次只能选择一个QGraphicView
小部件。
谁能给我一些想法?
谢谢
【问题讨论】:
只需重新实现mousePressEvent
。焦点处理也可以是一个案例。
@ilotXXI 在MainWindow
或每个QGraphicView
小部件中重新实现mousePressEvent
?
【参考方案1】:
您可以将installEventFilter 用于您的QGraphicsViews
并检测它们上的鼠标按下事件。因此,您可以根据需要定义当前视图并为其制作边框。小例子:
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
主窗口.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QGraphicsView>
namespace Ui
class MainWindow;
class MainWindow : public QMainWindow
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public:
bool eventFilter(QObject* watched, QEvent* event) override;
private:
Ui::MainWindow *ui;
QGraphicsView* view1_;
QGraphicsView* view2_;
QGraphicsView* selectedView_;
;
#endif // MAINWINDOW_H
主窗口.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QGridLayout>
#include <QMessageBox>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
view1_(nullptr),
view2_(nullptr),
selectedView_(nullptr)
ui->setupUi(this);
QGridLayout* grid = new QGridLayout(this->centralWidget());
view1_ = new QGraphicsView(this);
view2_ = new QGraphicsView(this);
grid->addWidget(view1_, 0, 0);
grid->addWidget(view2_, 0, 1);
view1_->viewport()->installEventFilter(this);
view2_->viewport()->installEventFilter(this);
MainWindow::~MainWindow()
delete ui;
bool MainWindow::eventFilter(QObject* watched, QEvent* event)
qDebug() << event->type();
if (event->type() == QEvent::MouseButtonPress)
if (watched == view1_->viewport())
selectedView_ = view1_;
QMessageBox::information(this, "!", "First");
return false;
else if (watched == view2_->viewport())
selectedView_ = view2_;
QMessageBox::information(this, "!", "Second");
return false;
return QMainWindow::eventFilter(watched, event);
【讨论】:
感谢您的回答。还有一个问题:如果我允许用户在QGridLayout
中动态分配QGraphicsView
小部件的数量。那么,是否有合适的方法来处理相同的选择问题?您当前的实现是针对固定数量的QGraphicsView
小部件。
如果用户动态设置 QGraphicsViews 的数量,approch 将与两个小部件相同。为每个 QGraphicsView 设置事件过滤器,并在 eventFilter 方法中确定选择了哪个小部件。我没有看到问题。你能描述一下有什么不同吗?
我在这里有问题。如果用户动态设置QGraphicsView
s 的数量,例如 9,然后用户将其更改为 4。我是否应该删除之前的 9 个QGraphicsView
s 并重新新建 4 个QGraphicsView
s 并将它们放入向量中。 (std::vector<QGraphicsView *>
)。或者有没有更聪明的方法来做QGraphicsView
s的动态分配
如果你知道 QGraphicsViews 的最大数量,用户可以选择,例如 9,你可以创建这样数量的 QGraphicsViews 对象并将它们放在向量中。当用户将数字更改为 4 时,您可以从布局中删除一些 QGraphicsView,但不能从矢量中删除。我认为,每次都重新创建对象,当用户更改次数不好时,最好创建一次对象,然后重复使用。【参考方案2】:
如果您只想更改鼠标悬停时的边框颜色,则不需要如此复杂的编程。 Qt supports 样式表,就像 CSS 一样。
在这种情况下,将以下样式表附加到您的 MainWindow
就足够了。
QGraphicsView:hover
border-style: solid;
border-width: 2px;
border-color: green;
有两种方法可以做到这一点:
使用设计器:首先选择MainWindow
,然后在其属性面板中单击styleSheet
,然后复制并粘贴样式表。
使用代码:使用QMainWindow
的setStyleSheet(...)
方法,并将样式表作为字符串传递。
【讨论】:
感谢您的回答。实际上,我设置了一个QComboBox
以允许用户选择他们需要的QGraphicsView
小部件的数量。比如用户设置QComboBox
为9,那么上图就是结果。然后,我想确定用户单击了哪个QGraphicsView
小部件,并将视频流插入到选定的QGraphicsView
小部件。
@Johnnylin 很简单,看看QSignalMapper
就行了。对于边框样式,样式表是可以的。以上是关于如何将 QMainWindow 鼠标点击位置传递给 QGraphicsView的主要内容,如果未能解决你的问题,请参考以下文章