qt主框架状态栏中实时显示QGraphicsView中图元QGraphicsItem的鼠标坐标

首先,新建一个QT Widget项目工程,删除MainWindow.ui中的菜单栏,并添加一个GraphicsView控件。

一,为工具栏添加openImage动作:

将openImage.png放在工程目录下新建的res文件夹中。

在工程目录下创建qrc文件,  vi res.qrc如下:


   
      res/openImage.png
   

接着在项目中导入该qrc文件

在MainWindow类的构造函数中ui->setupUi(this);下面添加代码创建newAction动作并加到主工具栏,用以打开图像:

ui->setupUi(this);

QAction *newAction = new QAction(tr("&New"),this);
newAction->setIcon(QIcon(":/res/openImage.png"));
connect(newAction, SIGNAL(triggered()), this, SLOT(newFile()));
ui->mainToolBar->addAction(newAction);

 声明及定义槽函数newFile,打开图像并在QGraphicsView控件中显示。

void MainWindow::newFile()
{
    QMessageBox::warning(this,"open file","openfile");
    QString fileName = QFileDialog::getOpenFileName(this,
                                                    tr("Open Input Image"),
                                                    QDir::currentPath(),
                                                    tr("image") + "(*.jpg *.png *bmp)");
    if(fileName != "")
    {
        QImage *image = new QImage;
        if(image->load(fileName))
        {
            QGraphicsScene *scene = new QGraphicsScene;
            scene->addPixmap(QPixmap::fromImage(*image));
            ui->graphicsView->setScene(scene);
            ui->graphicsView->show();
        }
    }
}

 后面,为了使用模型视图框架,通过QGraphicsItem类获取图元坐标,将以上打开图片函数改写如下:

private:
    Ui::MainWindow *ui;
    QLabel *statusLabel;
    QGraphicsScene scene;
    QGraphicsPixmapItem pixmapItem;
    QImage image;

 

void MainWindow::newFile()
{
    QString fileName = QFileDialog::getOpenFileName(this,
                                                    tr("Open Input Image"),
                                                    QDir::currentPath(),
                                                    tr("image") + "(*.jpg *.png *bmp)");
    if(fileName != "")
    {
        if(image.load(fileName))
        {
            ui->graphicsView->setScene(&scene);
            pixmapItem.setPixmap(QPixmap::fromImage(image));
            scene.addItem(&pixmapItem);
        }
    }

    pixmapItem.setAcceptHoverEvents(true);

    connect(ui->graphicsView,&QMyGraphicsView::updateItemPos,this,&MainWindow::updateItemPos);
}

至此,我们能打开一幅图像并显示在GraphicdView控件上。现在需要来实现捕捉鼠标实时移动坐标,而且是显示图元QGraphicsItem的坐标,而不是场景QGraphicsScene或是视图QgraphicsView坐标。

pixmapItem.setAcceptHoverEvents(true);为图元QGraphicsPixmapItem设置鼠标不点击也捕捉鼠标移动事件。

项目中添加一个新的C++类QMyGraphicsView,Base class基类先保持Custom,修改该类使其继承于QGraphicsView。

#ifndef QMYGRAPHICSVIEW_H
#define QMYGRAPHICSVIEW_H

#include 

class QMyGraphicsView : public QGraphicsView
{
    Q_OBJECT
public:
    QMyGraphicsView(QWidget *parent = nullptr);
};

#endif // QMYGRAPHICSVIEW_H
#include "qmygraphicsview.h"

QMyGraphicsView::QMyGraphicsView(QWidget *parent) : QGraphicsView(parent)
{

}

上面的修改有几点需要注意:

第一,添加QGraphicsView头文件

第二,添加Q_OBJECT宏,使该类有能处理信号槽等功能

第三,构造函数中添加父组件参数QWidget *parent,parent参数指明了组件的父组件,这样,当父组件delete时,Qt可以保证所有子组件,也就是parent指针指向这个组件的所有子组件,都会被正确的delete掉。

现在,我们将ui中的QGraphicsView控件提升promote to为刚才定义的QGraphicsView的子类

右键单击grahicsView控件——》promote to——》promoted class name: QMyGraphicsView——》点Add——》点promote,这时,会发现属性栏上graphicsview控件的类变成了QMyGrahicsView。现在,我们在该类中实现的功能就能在graphicsview控件上运用。

现在需要捕捉鼠标移动坐标,为QMyGrahicsView类添加重载函数mouseMoveEvent(QMouseEvent *event);

void QMyGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
    if (QGraphicsItem *item = itemAt(event->pos()))
    {
        QPointF sceneMousePos = this->mapToScene(event->pos());
        itemMousePos = item->mapFromScene(sceneMousePos);
        emit updateItemPos(itemMousePos);
    }
    else {
        QPointF p(0,0);
        emit updateItemPos(p);
    }
}

第一,首先QGraphicsView类中itemAt能获取鼠标所在的图元QGraphicsItem,再将视图坐标event->pos()用maptoScene转换成场景坐标sceneMousePos,图元类的mapFromScene将场景坐标sceneMousPos转为图元坐标itemMouePos。

另外,如果鼠标移动到图元以外,则坐标都显示(0,0)。

第二,定义信号updateItemPos将图元坐标发送给主框架:

signals:
    void updateItemPos(QPointF &pos);

第三,在主框架MainWindow.h中声明槽函数,用以更新显示图元坐标;创建显示坐标的QLabel添加至状态栏。

private slots:
    void newFile();
    void updateItemPos(QPointF pos );

 打开图像后建立信号槽连接,如上newFile槽函数中:

connect(ui->graphicsView,&QMyGraphicsView::updateItemPos,this,&MainWindow::updateItemPos);

MainWindow.cpp构造函数中:

statusLabel = new QLabel;
statusLabel->resize(200,30);
statusLabel->setText("coordinate:");
ui->statusBar->addPermanentWidget(statusLabel);

 槽函数中更新图元坐标:

void MainWindow::updateItemPos(QPointF pos)
{
    QMessageBox::warning(this,"receive signal","openfile");
    QString str = QString("coordinate: ") + "(" + QString::number(pos.x()) + "," + QString::number(pos.y()) + ")";
    statusLabel->setText(str);
}

效果图:

qt主框架状态栏中实时显示QGraphicsView中图元QGraphicsItem的鼠标坐标_第1张图片

 截图看不见鼠标,鼠标在原图片上,则显示实时坐标,图片之外显示0,0

完整源码https://download.csdn.net/download/jellocomeon/12159306

你可能感兴趣的:(C++,linux)