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; //视图移动参数x
double m_posy; //试图移动参数y
int 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)
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());
/
使命召唤6最低配置/ 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);
//画点
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论