1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > qt QGraphicsView实现鼠标中键拖动图片 鼠标滚轮缩放 两个窗口联动左键选点等功能

qt QGraphicsView实现鼠标中键拖动图片 鼠标滚轮缩放 两个窗口联动左键选点等功能

时间:2019-02-08 02:48:53

相关推荐

qt QGraphicsView实现鼠标中键拖动图片 鼠标滚轮缩放 两个窗口联动左键选点等功能

先看效果

(1)c++版本(一个动图)

(2)pyqt版本(一个图):与c++版本一毛一样,用的同一个ui文件,此处动图略

实现关键点:1)拖动:重写QGraphicsView类,鼠标中键按下记录位置并更改鼠标样式为手型,鼠标中键弹起记录鼠标位置,并执行拖动,通过设置横竖滚动条位置实现拖动;2)缩放:重写鼠标滚轮滑动事件滚轮上滑放大,下滑缩小即可;3)联动:设置联动参数,一个当前缩放参数,两个当前横竖滚轮位置参数。通过这三个参数进行联动;4)选点:左键选点,左键勾勒区域折点,右键停止并自动封闭。

源代码——c++版本

步骤(关键在于QgraphicsView类的重写,所有功能的实现均封装在这个类里边

(1)打开qtcreater,新建一个空的qt Application项目,并添加两个QgraphicsView控件用于显示图片,与一个textedit控件用于输出选点内容,并设置好布局

(2)改写QGraphicsView类,新建一个MyQGraphicsView类,继承QGraphicsView类,新建的这个类对应的头文件MyQGraphicsView.h如下:

#ifndef MYQGRAPHICSVIEW_H#define MYQGRAPHICSVIEW_H#pragma execution_character_set("UTF-8")#include <QKeyEvent>#include <QGraphicsView>#include <QGraphicsScene>#include <QGraphicsPixmapItem>#include <QMouseEvent>#include <QScrollBar>#include <QPen>#include <vector>class MyQGraphicsView: public QGraphicsView{private:QPointF GetMeanPos(std::vector<QPointF> data);//获取一组点中间位置protected:void wheelEvent(QWheelEvent *event) Q_DECL_OVERRIDE;void mousePressEvent(QMouseEvent *event) Q_DECL_OVERRIDE;void mouseReleaseEvent(QMouseEvent *event) Q_DECL_OVERRIDE;private:double m_scalnum; //缩放系数QPointF m_startpos; //鼠标中建开始点QPointF m_endpos; //鼠标中建结束点double m_posx; //视图移动参数xdouble m_posy; //试图移动参数yint m_flag; //是否进行选点int m_linkflag; //是否进行联动MyQGraphicsView *m_linkgraphicsview; //进行联动的窗口std::vector<QPointF> m_points; //选择的点std::vector<std::vector<QPointF>> m_allpoints; //选择的所有点public:explicit MyQGraphicsView(QWidget *parent = 0);void SetImage(QImage img);// 设置是否进行联动void SetLinkFlag(int flag){m_linkflag = flag;}//设置联动窗口void SetLinkWidget(MyQGraphicsView *graphicsview){m_linkgraphicsview = graphicsview;}// 设置联动参数void SetLinkPara(double para[3]);// 获取联动参数double* GetLinkPara(){double *para = new double[3];para[0] = m_scalnum;para[1] = m_posx;para[2] = m_posy;return para;}// view初始化void InitializeView(){m_points.clear();m_allpoints.clear();m_flag = 0;m_scalnum = 1;this->setCursor(Qt::ArrowCursor);}//设置是否选点void SetChoosePoint(int flag){m_flag = flag;if (flag == 0){this->setCursor(Qt::ArrowCursor);}else if (flag == 1 || flag == 2){this->setCursor(Qt::CrossCursor);}}//获取当前选点状态int GetFlag(){return m_flag;}//获取单个区域点集std::vector<QPointF> GetPoints(){return m_points;}//删除单个点集void ClearPoints(){m_points.clear();}//获取所有点集std::vector<std::vector<QPointF>> GetAllPoints(){return m_allpoints;}//删除所有点集void CalerAllPoints(){m_allpoints.clear();}};#endif // MYQGRAPHICSVIEW_H

新建的这个类对应的头文件MyQGraphicsView.cpp如下:

#include "MyQGraphicsView.h"#include <QDebug>MyQGraphicsView::MyQGraphicsView(QWidget *parent):QGraphicsView(parent){//设置鼠标样式// setCursor(Qt::CrossCursor);//使用抗锯齿渲染// setRenderHint(QPainter::Antialiasing);//设置缓冲背景,加速渲染// setCacheMode(QGraphicsView::CacheBackground);// setStyleSheet("border: 1px solid black");// setAlignment(Qt::AlignVCenter | Qt::AlignTop);// this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);// this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);m_scalnum = 1.;m_flag = 0;setMouseTracking(true);}void MyQGraphicsView::SetLinkPara(double para[3]){double scalenum = para[0];double posx = para[1];double posy = para[2];//设置缩放if (scalenum > m_scalnum){this->scale(1.3, 1.3);m_scalnum *= 1.3;}else if (scalenum < m_scalnum){this->scale(1/1.3, 1/1.3);m_scalnum /= 1.3;}//设置移动if (posx != m_posx && posy != m_posy){this->horizontalScrollBar()->setValue(posx);this->verticalScrollBar()->setValue(posy);m_posx = posx;m_posy = posy;}}void MyQGraphicsView::wheelEvent(QWheelEvent *event){if(event->delta()>0){this->scale(1.3, 1.3);m_scalnum *= 1.3;}else{this->scale(1/1.3, 1/1.3);m_scalnum /= 1.3;}if (m_linkflag == 1){m_linkgraphicsview->SetLinkPara(this->GetLinkPara());}QGraphicsView::wheelEvent(event);}void MyQGraphicsView::mousePressEvent(QMouseEvent *event){if (event->button() == Qt::MiddleButton){this->setCursor(Qt::PointingHandCursor);m_startpos = mapToScene(event->pos());}//鼠标左键选点并画线else if (event->button() == Qt::LeftButton && m_flag == 1){QPointF p = this->mapToScene(event->pos());// qDebug()<<p;m_points.push_back(p);//绘制点QPen *pen = new QPen();pen->setColor(QColor(255, 0, 0));pen->setWidth(2);this->scene()->addEllipse(p.x()-1, p.y()-1, 2, 2, *pen);int num = m_points.size();//绘制线if (num >= 2){pen->setColor(QColor(241, 89, 42));pen->setWidth(1);this->scene()->addLine(m_points[num-2].x(),m_points[num-2].y(),m_points[num-1].x(),m_points[num-1].y(),*pen);}}//鼠标左键只选点else if (event->button() == Qt::LeftButton && m_flag == 2){QPointF p = this->mapToScene(event->pos());m_points.push_back(p);//画点QPen *pen = new QPen();pen->setColor(QColor(255, 0, 0));pen->setWidth(2);this->scene()->addEllipse(p.x()-1, p.y()-1, 4, 4, *pen);//添加文本QFont *font = new QFont("Roman times", 20, QFont::Bold);QGraphicsTextItem *text = new QGraphicsTextItem(QString::number(m_points.size()));text->setPos(p.x()-10, p.y()-10);text->setDefaultTextColor(QColor(248, 201, 0));text->setFont(*font);this->scene()->addItem(text);}//鼠标右键完成当前区域选点else if (event->button() == Qt::RightButton && m_flag == 1){m_allpoints.push_back(m_points);//连接终点与起点QPen *pen = new QPen();pen->setColor(QColor(241, 89, 42));pen->setWidth(1);int num = m_points.size() - 1;// qDebug()<<m_points[num];this->scene()->addLine(m_points[num].x(),m_points[num].y(),m_points[0].x(),m_points[0].y(),*pen);//添加文本QFont *font = new QFont("Roman times", 20, QFont::Bold);QGraphicsTextItem *text = new QGraphicsTextItem(QString::number(m_allpoints.size()));QPointF mpos = GetMeanPos(m_points);text->setPos(mpos.x()-20, mpos.y()-20);text->setDefaultTextColor(QColor(248, 201, 0));text->setFont(*font);this->scene()->addItem(text);//清除已经选好的点集m_points.clear();}QGraphicsView::mousePressEvent(event);}void MyQGraphicsView::mouseReleaseEvent(QMouseEvent *event){//鼠标中建弹起进行视图移动if (event->button() == Qt::MiddleButton){if (m_flag != 0)this->setCursor(Qt::CrossCursor);elsethis->setCursor(Qt::ArrowCursor);m_endpos = mapToScene(event->pos());//获取滚动条当前位置double oposx = this->horizontalScrollBar()->value();double oposy = this->verticalScrollBar()->value();//计算鼠标移动的距离QPointF offset = m_endpos - m_startpos;//计算新的滚轮位置double nposx = oposx-offset.x()*m_scalnum;double nposy = oposy-offset.y()*m_scalnum;//设置新的滚轮位置this->horizontalScrollBar()->setValue(nposx);this->verticalScrollBar()->setValue(nposy);// QPointF offset = -m_endpos + m_startpos;// this->scene()->setSceneRect(this->scene()->sceneRect().x()+offset.x(),//this->scene()->sceneRect().y()+offset.y(),//this->scene()->sceneRect().width(),//this->scene()->sceneRect().height());this->scene()->update();//记录备用m_posx = nposx;m_posy = nposy;//进行联动if (m_linkflag == 1){m_linkgraphicsview->SetLinkPara(this->GetLinkPara());}}QGraphicsView::mouseReleaseEvent(event);}void MyQGraphicsView::SetImage(QImage img){//把影像添加到画布QPixmap Images = QPixmap::fromImage(img);QGraphicsPixmapItem *map = new QGraphicsPixmapItem(Images);// map = new QGraphicsPixmapItem(Images);map->setFlag(QGraphicsPixmapItem::ItemIsSelectable, true);map->setFlag(QGraphicsPixmapItem::ItemIsMovable, false);map->setFlag(QGraphicsPixmapItem::ItemSendsGeometryChanges,true);QGraphicsScene *scene = new QGraphicsScene(); //场景 = new QGraphicsScene();//画布添加至场景scene->addItem(map);//场景绑定到控件this->setScene(scene);this->show();}QPointF MyQGraphicsView::GetMeanPos(std::vector<QPointF> data){double sumx(0);double sumy(0);for (int i(0); i<data.size(); ++i){sumx += data[i].x();sumy += data[i].y();}return QPointF(sumx/data.size(), sumy/data.size());}

(3)将原有新建的QGraphicsView控件提升为新建的类

(4)在主窗体构造函数中添加以下内容:

QgraphicsViewTestGUI::QgraphicsViewTestGUI(QWidget *parent): QWidget(parent), ui(new Ui::QgraphicsViewTestGUI){ui->setupUi(this);//窗口最大化showMaximized();//设置事件过滤器,用于选点测试ui->graphicsView_LeftImage->viewport()->installEventFilter(this);ui->graphicsView_RightImage->viewport()->installEventFilter(this);//设置窗口比例ui->splitter->setStretchFactor(0, 4);ui->splitter->setStretchFactor(1, 1);//设置联动ui->graphicsView_LeftImage->SetLinkFlag(1);ui->graphicsView_RightImage->SetLinkFlag(1);ui->graphicsView_LeftImage->SetLinkWidget(ui->graphicsView_RightImage);ui->graphicsView_RightImage->SetLinkWidget(ui->graphicsView_LeftImage);//显示图片QImage img1("E:/smallthings/temp/QgraphicsViewTestGUI/testimg.jpg");QImage img2("E:/smallthings/temp/QgraphicsViewTestGUI/testimg.jpg");ui->graphicsView_LeftImage->SetImage(img1);ui->graphicsView_RightImage->SetImage(img2);//设置选点ui->graphicsView_LeftImage->SetChoosePoint(2);//左边窗口测试选点ui->graphicsView_RightImage->SetChoosePoint(1);//右边窗口测试选区域}

(5)在主窗体类中添加两个函数

函数声明:

bool eventFilter(QObject* watched, QEvent* event);//事件过滤void ShowMsg(QString msg);//显示日志

函数实现:

bool QgraphicsViewTestGUI::eventFilter(QObject* watched, QEvent* event){if (event->type() == QEvent::MouseButtonPress){QMouseEvent *mouseevent = static_cast<QMouseEvent*>(event);if(mouseevent->button() == Qt::LeftButton && watched == ui->graphicsView_LeftImage->viewport()){//左窗口测试选点(左键)std::vector<QPointF> ps = ui->graphicsView_LeftImage->GetPoints();if (ps.size() != 0){QPointF nowp = ps.at(ps.size() - 1);ShowMsg("影像选点测试,影像上一个点第" +QString::number(ps.size()) +"个点,坐标为:(" +QString::number(nowp.x(), 'f', 3) +"," +QString::number(nowp.y(), 'f', 3) + ")");}}else if(mouseevent->button() == Qt::RightButton && watched == ui->graphicsView_RightImage->viewport()){//右键测试选区域(右键)std::vector<std::vector<QPointF>> areas = ui->graphicsView_RightImage->GetAllPoints();if (areas.size() != 0){std::vector<QPointF> nowarea = areas.at(areas.size() - 1);QString coorstr = "";for (int i(0); i<nowarea.size(); ++i){QString tstr = "(" +QString::number(nowarea[i].x(), 'f', 3) +", " +QString::number(nowarea[i].y(), 'f', 3) +")\n";coorstr += tstr;}ShowMsg("影像选区域测试,影像上一个区域第" +QString::number(areas.size()) +"个区域,坐标集为:\n" + coorstr);}}}return QObject::eventFilter(watched, event);}//输出日志void QgraphicsViewTestGUI::ShowMsg(QString msg){ui->textBrowser_log->moveCursor(QTextCursor::End);ui->textBrowser_log->append(">>" + msg);}

(6)愉快的运行

源代码——pyqt版本

依赖项

PyQt5 == 5.10.1

numpy == 1.21.4

qimage2ndarray == 1.8.3

步骤(关键在于QgraphicsView类的重写,所有功能的实现均封装在这个类里边

(1)新建一个python脚本,里边新建一个MyQgraphicsView类,继承QgraphicsView类,添加如下代码。注:pyqt版本支持的影像为numpy矩阵,可以是多通道的遥感影像,但默认前三个通道为RGB;数据类型可以不是uint8(比如uint16),会自动进行2%线性拉伸,去除过大、过小的异常值,同时数据拉伸到uint8范围内

# yangzhen# .12.04from PyQt5 import QtCore as qcfrom PyQt5 import QtGui as qgfrom PyQt5 import QtWidgets as qwimport numpy as npimport copyclass MyQGraphicsView(qw.QGraphicsView):def __init__(self, parent):super(MyQGraphicsView, self).__init__(parent)self.setMouseTracking(True)self.points = [] # 选择的点self.allpoints = []self.startpos = qc.QPoint(0, 0) # 鼠标中键按下时起始点self.endpos = qc.QPoint(0, 0) # 鼠标中键弹起时终点self.scalenum = 1 # 缩放系数# self.scaleflag = 0 # 放大还是缩小(0:不动,1:放大,-1:缩小)self.nposx = 0 # 视图移动参数xself.nposy = 0 # 视图移动参数y# self.mindex = 1 # 当前区域编号self.flag = 0 # 是否进行选点的flagself.linkflag = 0 # 是否进行联动def SetLinkFlag(self, flag):"""设置是否联动"""self.linkflag = flagdef SetLinkWidget(self, mwidget):self.linkwidget = mwidgetdef SetLinkPara(self, para):"""设置联动参数并作出联动操作"""scalenum = para[0]# print(scaleflag)nposx = para[1]nposy = para[2]# 设置缩放if scalenum > self.scalenum:self.scale(1.3, 1.3)self.scalenum = self.scalenum*1.3# self.scalflag = 1elif scalenum < self.scalenum:self.scale(1/1.3, 1/1.3)self.scalenum = self.scalenum/1.3# self.scalflag = -1# 设置移动if nposx != self.nposx and nposy != self.nposy:self.horizontalScrollBar().setValue(nposx)self.verticalScrollBar().setValue(nposy)self.nposx = nposxself.nposy = nposydef GetLinkPara(self):"""获取联动参数"""para = []para.append(self.scalenum)para.append(self.nposx)para.append(self.nposy)return paradef InitializeView(self):"""View初始化"""self.points.clear()self.allpoints.clear()self.flag = 0self.scalenum = 1self.setCursor(qc.Qt.ArrowCursor)def SetChoosePoint(self, flag):"""设置是否选点"""self.flag = flagif flag == 0:self.setCursor(qc.Qt.ArrowCursor)if flag == 1 or flag == 2:self.setCursor(qc.Qt.CrossCursor)def GetFlag(self):"""获取当前是在做什么"""return self.flagdef GetPoints(self):"""获取点集"""return self.pointsdef ClearPoints(self):"""删除点集"""self.points.clear()def GetAllPoints(self):"""获取所有区域点集"""return self.allpointsdef ClearPoints(self):"""删除所有区域点集合"""self.allpoints.clear()def PersentLiner(self, data, ratio):mdata = data.copy()rows, cols = data.shape[0:2]counts = rows*colsmdata = mdata.reshape(counts, 1)tdata = np.sort(mdata, axis=0)cutmin = tdata[int(counts*ratio), 0]cutmax = tdata[int(counts*(1-ratio)), 0]ndata = 255.0*(data.astype(np.float32) - cutmin)/float(cutmax-cutmin)ndata[data < cutmin] = 0ndata[data > cutmax] = 255return ndatadef SetImage(self, data):"""设置影像"""# if (data.type() == )dtp = data.dtyperows, cols, depth = data.shape# 如果通道数大于3个,只保留前边三个通道if depth > 3:img = data[:, :, 0:3].copy()img = img[:, :, ::-1]else:img = data.copy()rows, cols, depth = img.shape# 如果不是uint8的数据,需要先拉伸if dtp != np.uint8:for i in range(depth):img[:,:,i] = self.PersentLiner(img[:,:,i].copy(), 0.02)img = img.astype(np.uint8)# numpy矩阵转换成QImageif depth == 3:nimg = qg.QImage(img.data, cols, rows, cols*depth,\qg.QImage.Format_RGB888)elif depth == 2:b1 = np.float32(img[:, :, 0])b2 = np.float32(img[:, :, 1])img = np.uint8((b1+b2)/2.)nimg = qg.QImage(img.data, cols, rows, cols*depth,\qg.QImage.Format_Grayscale8)elif depth == 1:nimg = qg.QImage(img.data, cols, rows, cols*depth,\qg.QImage.Format_Grayscale8)pix = qg.QPixmap.fromImage(nimg)item = qw.QGraphicsPixmapItem(pix)showscene = qw.QGraphicsScene()showscene.addItem(item) self.setScene(showscene)self.setTransform(qg.QTransform())def wheelEvent(self, event):if (event.angleDelta().y() > 0.5):self.scale(1.3, 1.3)self.scalenum = self.scalenum * 1.3# self.scaleflag = 1elif (event.angleDelta().y() < 0.5):self.scale(1/1.3, 1/1.3)# self.scaleflag = -1self.scalenum = self.scalenum / 1.3if self.linkflag == 1:self.linkwidget.SetLinkPara(self.GetLinkPara())def mousePressEvent(self, event):button = event.button()modifier = event.modifiers()# 按住ctrl时变更鼠标样式if button == qc.Qt.MiddleButton:self.setCursor(qc.Qt.PointingHandCursor)self.startpos = self.mapToScene(event.pos())# print(self.startpos)# 鼠标左键进行选点elif button == qc.Qt.LeftButton and self.flag == 1:p = self.mapToScene(event.pos())self.points.append([p.x(), p.y()])# 画点pen = qg.QPen()pen.setColor(qg.QColor(255, 0, 0))pen.setWidth(2)self.scene().addEllipse(p.x()-1, p.y()-1, 2, 2, pen)num = len(self.points)# 画线if num>=2:pen.setColor(qg.QColor(241, 89, 42))pen.setWidth(1)self.scene().addLine(self.points[num-2][0], \self.points[num-2][1], \self.points[num-1][0], \self.points[num-1][1], pen)# 鼠标左键只选点elif button == qc.Qt.LeftButton and self.flag == 2:p = self.mapToScene(event.pos())self.points.append([p.x(), p.y()])# 画点pen = qg.QPen()pen.setColor(qg.QColor(255, 0, 0))pen.setWidth(2)self.scene().addEllipse(p.x()-1, p.y()-1, 4, 4, pen)# 添加文本font = qg.QFont("Roman times", 20, qg.QFont.Bold)text = qw.QGraphicsTextItem(str(len(self.points)))text.setPos(p.x()-10, p.y()-10)text.setDefaultTextColor(qg.QColor(248, 201, 0))text.setFont(font)self.scene().addItem(text)# 鼠标右键完成当前区域选点elif button == qc.Qt.RightButton and self.flag == 1:self.allpoints.append(copy.deepcopy(self.points))# 画线pen = qg.QPen()pen.setColor(qg.QColor(241, 89, 42))pen.setWidth(1)self.scene().addLine(self.points[-1][0], \self.points[-1][1], \self.points[0][0], \self.points[0][1], pen)# 添加文本tps = np.array(self.points)mps = np.mean(tps, axis=0)font = qg.QFont("Roman times", 20, qg.QFont.Bold)text = qw.QGraphicsTextItem(str(len(self.allpoints)))text.setPos(mps[0]-20, mps[1]-20)text.setDefaultTextColor(qg.QColor(248, 201, 0))text.setFont(font)self.scene().addItem(text)# 这个区域点压入集合self.points.clear()def mouseReleaseEvent(self, event):button = event.button()modifier = event.modifiers()# 鼠标中键弹起时进行视图移动if button == qc.Qt.MiddleButton:# 变更鼠标样式if self.flag == 0:self.setCursor(qc.Qt.ArrowCursor)elif self.flag == 1 or self.flag == 2:self.setCursor(qc.Qt.CrossCursor)# 记录当前点进行视图移动self.endpos = self.mapToScene(event.pos())# 获取滚动条当前位置oposx = self.horizontalScrollBar().value()oposy = self.verticalScrollBar().value()# 计算鼠标移动的距离offset = self.endpos - self.startpos# 根据移动的距离计算新的滚轮位置nposx = oposx - offset.x()*self.scalenumnposy = oposy - offset.y()*self.scalenum# 设置新的滚轮位置self.horizontalScrollBar().setValue(nposx)self.verticalScrollBar().setValue(nposy)# 记录一下备用self.nposx = nposxself.nposy = nposy# 进行联动if self.linkflag == 1:self.linkwidget.SetLinkPara(self.GetLinkPara())

(2)再新建一个python脚本,新建一个QgraphicsViewTestGUI类,继承QWidget类,代码如下:

# yangzhen# .12.04from PyQt5 import QtCore, QtGui, QtWidgetsimport ImageShowimport numpy as npimport qimage2ndarrayclass QgraphicsViewTestGUI(QtWidgets.QWidget):def __init__(self):super(QgraphicsViewTestGUI, self).__init__()self.showMaximized()# 设置主布局为格网布局self.gridLayout = QtWidgets.QGridLayout(self)self.gridLayout.setObjectName("gridLayout")# 日志输出窗口与两个影像窗口为垂直分割布局self.splitter = QtWidgets.QSplitter(self)self.splitter.setOrientation(QtCore.Qt.Vertical)self.splitter.setObjectName("splitter")# 为两个影像显示窗口设置布局self.layoutWidget = QtWidgets.QWidget(self.splitter)self.layoutWidget.setObjectName("layoutWidget")self.horizontalLayout = QtWidgets.QHBoxLayout(self.layoutWidget)self.horizontalLayout.setContentsMargins(0, 0, 0, 0)self.horizontalLayout.setObjectName("horizontalLayout")# 左影像显示窗口self.graphicsView_LeftImage = ImageShow.MyQGraphicsView(self.layoutWidget)self.graphicsView_LeftImage.setObjectName("graphicsView_LeftImage")self.horizontalLayout.addWidget(self.graphicsView_LeftImage)# 右影像显示窗口self.graphicsView_RightImage = ImageShow.MyQGraphicsView(self.layoutWidget)self.graphicsView_RightImage.setObjectName("graphicsView_RightImage")self.horizontalLayout.addWidget(self.graphicsView_RightImage)# 日志输出窗口self.textBrowser_log = QtWidgets.QTextBrowser(self.splitter)self.textBrowser_log.setStyleSheet("QTextBrowser\n""{\n"" background:white;\n"" font-size:20px;\n"" font-family:微软雅黑;\n"" font-weight:bold;\n""}")self.textBrowser_log.setObjectName("textBrowser_log")self.gridLayout.addWidget(self.splitter, 0, 0, 1, 1)# 初始化窗口self.Initialize()def Initialize(self):"""窗口初始化用于影像显示的测试"""# 设置事件过滤,用于选点测试self.graphicsView_LeftImage.viewport().installEventFilter(self)self.graphicsView_RightImage.viewport().installEventFilter(self)# 设置窗口比例self.splitter.setStretchFactor(0, 4)self.splitter.setStretchFactor(1, 1)# 设置联动self.graphicsView_LeftImage.SetLinkFlag(1)self.graphicsView_RightImage.SetLinkFlag(1)self.graphicsView_LeftImage.SetLinkWidget(self.graphicsView_RightImage)self.graphicsView_RightImage.SetLinkWidget(self.graphicsView_LeftImage)# 显示图片img1 = QtGui.QImage('E:/smallthings/temp/QgraphicsViewTestGUI/testimg.jpg')img2 = QtGui.QImage('E:/smallthings/temp/QgraphicsViewTestGUI/testimg.jpg')img1 = qimage2ndarray.rgb_view(img1)img2 = qimage2ndarray.rgb_view(img2)self.graphicsView_LeftImage.SetImage(img1)self.graphicsView_RightImage.SetImage(img2)# 设置选点self.graphicsView_LeftImage.SetChoosePoint(2)self.graphicsView_RightImage.SetChoosePoint(1)def eventFilter(self, watched, event): """重写eventfilter事件"""if event.type() == QtCore.QEvent.MouseButtonPress:if event.button() == QtCore.Qt.LeftButton and watched == self.graphicsView_LeftImage.viewport():ps = self.graphicsView_LeftImage.GetPoints()if len(ps) != 0:nowp = ps[-1]self.ShowMsg("影像选点测试,影像上一个点第" +str(len(ps)) +"个点,坐标为:(" +str('%.3f'%nowp[0]) + ", " +str('%.3f'%nowp[1]) + ")")elif event.button() == QtCore.Qt.RightButton and watched == self.graphicsView_RightImage.viewport():areas = self.graphicsView_RightImage.GetAllPoints()if len(areas) != 0:nowarea = areas[-1]coorstr = ''for coor in nowarea:tstr = "(" + str('%.3f'%coor[0]) + ", " + str('%.3f'%coor[1]) + ")\n"coorstr += tstrself.ShowMsg("影像选区域测试,影像上一个区域第" +str(len(areas)) +"个区域,坐标集为:\n" + coorstr)return QtWidgets.QWidget.eventFilter(self, watched, event)def ShowMsg(self, msg):"""追加的方式在ttextBrowser_log上写东西,为了日志的显示"""self.textBrowser_log.moveCursor(QtGui.QTextCursor.End)self.textBrowser_log.append('>>' + msg)if __name__ == '__main__':import sysapp = QtWidgets.QApplication(sys.argv)ui = QgraphicsViewTestGUI()ui.show()sys.exit(app.exec_())

(3)然后就可以愉快的运行了

后记

两个版本的源代码也是有的:

链接:/s/18E_Ll-FYItklE4MiGrKosw

提取码:1234

qt QGraphicsView实现鼠标中键拖动图片 鼠标滚轮缩放 两个窗口联动左键选点等功能(c++pyqt两个版本)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。