需求描述
在场景中实现拖动,缩放,并在场景的缩略图中显示其对应在视口中显示的矩形区域。
程序效果图如下:
开发环境:Qt 5.13.1
编译环境:MinGW64
项目结构:
直接上程序:
main.cpp
#include "dialog.h"
#include "log.hpp"
#include <QMutex>
#include <QDateTime>
#include <QFile>#include <QApplication>
void MessageTypePut(QtMsgType type, const QMessageLogContext &context, const QString &msg);
int main(int argc, char *argv[])
{
#ifdef OUTPUT_LOGqInstallMessageHandler(MessageTypePut);
#endifQApplication a(argc, argv);Dialog w;w.show();return a.exec();
}void MessageTypePut(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
// getCurrFilePath();static QMutex mutex;mutex.lock();QString text;switch(type){case QtDebugMsg:text = QString("Debug:");break;case QtWarningMsg:text = QString("Warning:");break;case QtCriticalMsg:text = QString("Critical:");break;case QtFatalMsg:text = QString("Fatal:");break;default:break;}//日志写到文件QString current_date_time = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");QString message = QString("%1 %2%3").arg(current_date_time).arg(text).arg(msg);QFile file(LOG_FILE);file.open(QIODevice::WriteOnly | QIODevice::Append);QTextStream text_stream(&file);text_stream << message << "\r\n";file.flush();//将缓冲的数据刷新到文件file.close();mutex.unlock();
}
breviarydlg.h
#ifndef BREVIARYDLG_H
#define BREVIARYDLG_H#include <QDialog>
#include "graphicsview.h"//视口的长宽比需要与缩略图的长宽比保持一致
#define SMALL_W 400
#define SMALL_H 400//class QGraphicsScene;
class MyGraphicsScene;
class QGraphicsView;
class QGraphicsPixmapItem;class BreviaryDlg : public QDialog
{Q_OBJECT
public:BreviaryDlg(QWidget *parent = nullptr, Qt::WindowFlags f = Qt::WindowFlags());void setSize(int w,int h);void setPosSize(int x,int y,int w,int h);void setPixmap(QPixmap &pix);QSize getSize();void fitInView();void transViewPtr(GraphicsView *view);
protected:void resizeEvent(QResizeEvent *event);
// void paintEvent(QPaintEvent *event);
public slots:void slot_setRectSize(QRect &rect);
private:QPixmap m_pixmap;
// bool isUpdate;QRect m_rect;
// QGraphicsScene *scene;MyGraphicsScene *scene;QGraphicsView *view;QGraphicsPixmapItem *item;GraphicsView *m_view1;
};
#endif // BREVIARYDLG_H
breviarydlg.cpp
#include "breviarydlg.h"
#include <QPalette>
#include <QPainter>
#include <QDebug>
#include <QGraphicsRectItem>
#include "MyGraphicsScene.h"
#include <QGraphicsView>BreviaryDlg::BreviaryDlg(QWidget *parent, Qt::WindowFlags f):QDialog(parent,f)/*,isUpdate(false)*/
{resize(SMALL_W,SMALL_H);setWindowFlag(Qt::FramelessWindowHint);//因为是场景所以加载背景会被场景覆盖,另外设置了无边框之后,场景也会覆盖窗口可以不用重绘窗口QPalette palette = this->palette();palette.setColor(QPalette::Background,QColor(34,34,34));setWindowOpacity(0.8);setPalette(palette);scene = new MyGraphicsScene(this);
// scene->setBackgroundBrush(QBrush(QColor(Qt::red)));
// scene->setForegroundBrush(QBrush(QColor(Qt::red)));
// scene->setSceneRect(0,0,400,400);view = new QGraphicsView(scene,this);view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);view->setGeometry(0,0,SMALL_W,SMALL_H);item = NULL;
}void BreviaryDlg::setSize(int w, int h)
{
// resize(w,h);setFixedSize(w,h);
}void BreviaryDlg::setPosSize(int x, int y, int w, int h)
{setGeometry(x,y,w,h);
}QSize BreviaryDlg::getSize()
{return QSize(SMALL_W,SMALL_H);
}void BreviaryDlg::setPixmap(QPixmap &pix)
{m_pixmap = pix;
// isUpdate = true;qDebug()<<"setPixmap";if (item != NULL){scene->removeItem(item);delete item;}if(m_pixmap.isNull()){qDebug()<<"pixmap is null";}/*加载Pixmap图片加载不上去,画布的大小与图片的尺寸不一*/item = scene->addPixmap(m_pixmap);//QPixmap(":/new/prefix1/11.png")fitInView();
}void BreviaryDlg::fitInView()
{QRectF bounds = view->scene()->itemsBoundingRect();view->fitInView(bounds, Qt::KeepAspectRatio);
}void BreviaryDlg::transViewPtr(GraphicsView *view)
{m_view1 = new GraphicsView;m_view1 = view;connect(scene,&MyGraphicsScene::previewRectMoved,m_view1,&GraphicsView::slot_MoveView);
}void BreviaryDlg::resizeEvent(QResizeEvent *event)
{QDialog::resizeEvent(event);fitInView();
}//void BreviaryDlg::paintEvent(QPaintEvent *event)
//{
// QPainter painter(this);
// QPen pen(QColor(34,34,34));//34,34,34
// pen.setWidth(2);
// pen.setStyle(Qt::SolidLine);// painter.drawRect(0,0,SMALL_W,SMALL_H);
//}void BreviaryDlg::slot_setRectSize(QRect &rect)
{m_rect = rect;scene->onSetPreviewRect(rect);
}
config.h
#ifndef CONFIG_H
#define CONFIG_H#include <QSettings>
#include <QVariant>class Config
{public:Config(QString qstrfilename = "");virtual ~Config(void);void Set(QString,QString,QVariant);QVariant Get(QString,QString);
private:QString m_qstrFileName;QSettings *m_psetting;
};#endif // CONFIG_H
config.cpp
#include "config.h"
#include <QCoreApplication>
#include <QDebug>Config::Config(QString qstrfilename)
{if (qstrfilename.isEmpty()){m_qstrFileName = QCoreApplication::applicationDirPath() + "/Config.ini";}else{m_qstrFileName = qstrfilename;}m_psetting = new QSettings(m_qstrFileName, QSettings::IniFormat);qDebug() << m_qstrFileName;
}
Config::~Config()
{delete m_psetting;m_psetting = 0;
}
void Config::Set(QString qstrnodename,QString qstrkeyname,QVariant qvarvalue)
{m_psetting->setValue(QString("/%1/%2").arg(qstrnodename).arg(qstrkeyname), qvarvalue);
}QVariant Config::Get(QString qstrnodename,QString qstrkeyname)
{QVariant qvar = m_psetting->value(QString("/%1/%2").arg(qstrnodename).arg(qstrkeyname));return qvar;
}
dialog.h
#ifndef DIALOG_H
#define DIALOG_H#include <QDialog>
#include <QGraphicsScene>
#include "graphicsview.h"
#include "breviarydlg.h"
#include <QTimer>struct stuRatio{qreal xRatio;qreal yRatio;
};#define SMALL_W 400
#define SMALL_H 400class QVideoWidget;
class QMediaPlayer;QT_BEGIN_NAMESPACE
namespace Ui { class Dialog; }
QT_END_NAMESPACEclass Dialog : public QDialog
{Q_OBJECTpublic:Dialog(QWidget *parent = nullptr);~Dialog();// void drawRect();stuRatio getScalingRatio();signals:void signalDrawRect(QRect &rect);void signalSetDrawRectSize();
private slots:void slot_createNaviBar(qreal scale);void slot_HvalueChanged(int value);void slot_VvalueChanged(int value);void slot_scrollValueChanged();void slot_setViewRect();void slot_timeout();
private:Ui::Dialog *ui;QGraphicsScene *scene;GraphicsView *view;QVideoWidget *video;QMediaPlayer *player;BreviaryDlg *dlg;QTimer *timer;qreal m_scale;QRect rectViewport;quint32 m_y;quint32 m_x;QSize m_viewSize;QString str;
};
#endif // DIALOG_H
dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
#include "log.hpp"
#include <QScrollBar>
#include <QSize>
#include <QGraphicsProxyWidget>
#include <QMediaPlayer>
#include <QVideoWidget>
//#include <QGraphicsRectItem>
#include <QGraphicsVideoItem>
#include <QPainter>Dialog::Dialog(QWidget *parent): QDialog(parent), ui(new Ui::Dialog),m_x(0),m_y(0),m_viewSize(100,100)
{ui->setupUi(this);resize(QSize(1200,1000));scene = new QGraphicsScene(this);view = new GraphicsView(scene,this);//设置了视图的父窗口之后就不需要调用show()
// scene->setSceneRect(0,0,800,800);
// view->setGeometry(0,0,800,800);
// view->show();//场景中播放视频
// QGraphicsRectItem *item = new QGraphicsRectItem(0,0,500,500);//item中手动嵌入的窗口的大小不会随item大小一致// video = new QVideoWidget(this);
// video->setWindowFlag(Qt::WindowStaysOnTopHint);
// video->resize(500,500);
// player = new QMediaPlayer(this);
// player->setVideoOutput(video);
// player->setMedia(QUrl::fromLocalFile("F:\\video\\汉化日记:第2话.mp4"));
// player->play();// QGraphicsProxyWidget *proxy = new QGraphicsProxyWidget(item);
// proxy->setWidget(video);
// scene->addItem(item);//场景中播放视频的正确打开方式QGraphicsVideoItem *item = new QGraphicsVideoItem();scene->addItem(item);item->setSize(QSizeF(800.0,800.0));player = new QMediaPlayer(this);player->setVideoOutput(item);player->setMedia(QUrl::fromLocalFile("F:\\video\\汉化日记:第2话.mp4"));player->play();connect(view,&GraphicsView::sinalCreateNavigaBar,this,&Dialog::slot_createNaviBar);dlg = NULL;str = QCoreApplication::applicationDirPath();str += "\\11.png";outPut<<"路径名:"<<str;timer = new QTimer;connect(timer,&QTimer::timeout,this,&Dialog::slot_timeout);connect(view->verticalScrollBar(),&QScrollBar::valueChanged,this,slot_VvalueChanged);connect(view->horizontalScrollBar(),&QScrollBar::valueChanged,this,slot_HvalueChanged);connect(this,&Dialog::signalSetDrawRectSize,this,&Dialog::slot_setViewRect);
}Dialog::~Dialog()
{delete ui;
}void Dialog::slot_createNaviBar(qreal scale)
{if(scale > 1){m_scale = scale;if(dlg == NULL){dlg = new BreviaryDlg(this,Qt::WindowStaysOnTopHint);// dlg->setGeometry(100,200,400,300);// dlg->setSize(400,300);connect(this,&Dialog::signalDrawRect,dlg,&BreviaryDlg::slot_setRectSize);// QImage image(QSize(400,300),QImage::Format_RGB32);// QPainter painter(&image);// image.save("E:\\11","png");// view->setViewport(dlg);// dlg->setPosSize(600,500,400,300);// QPalette palette = dlg->palette();// palette.setColor(QPalette::Background,QColor(34,34,34));// dlg->setWindowOpacity(0.8);// dlg->setPalette(palette);QSize size = dlg->getSize();view->smallWinSize(size);dlg->transViewPtr(view);dlg->show();//非模态}else{dlg->show();}QPixmap pixmap(SMALL_W,SMALL_H);pixmap.fill(Qt::transparent);QPainter painter(&pixmap);painter.setRenderHint(QPainter::Antialiasing);scene->render(&painter);pixmap.save(str,"png");dlg->setPixmap(pixmap);timer->start(100);}else{if(dlg != NULL){dlg->hide();}}
}void Dialog::slot_scrollValueChanged()
{m_viewSize = view->viewportSizeHint();//获取视口大小QRect rectScene = scene->itemsBoundingRect().toRect();if (view->horizontalScrollBar()->isHidden()){rectViewport.setX(rectScene.x());rectViewport.setWidth(rectScene.width());}if(view->verticalScrollBar()->isHidden()){rectViewport.setY(0);rectViewport.setHeight(rectScene.height());}emit signalSetDrawRectSize();
}void Dialog::slot_HvalueChanged(int value)
{m_viewSize = view->viewportSizeHint();//获取视口大小outPut<<"slot_HvalueChanged"<<" "<<m_viewSize<</*" "<<rect<<" "<<*/value;if(value != 0 && dlg != NULL){if(dlg->isVisible()){m_x = value;emit signalSetDrawRectSize();}}
}void Dialog::slot_VvalueChanged(int value)
{m_viewSize = view->viewportSizeHint();//获取视口大小
// QRect rect = view->viewPortRect();outPut<<"slot_VvalueChanged"<<" "<<m_viewSize<</*" "<<rect<<" "<<*/value;if(value != 0 && dlg != NULL){if(dlg->isVisible()){m_y = value;emit signalSetDrawRectSize();}}
}void Dialog::slot_setViewRect()
{view->viewPortSize(m_viewSize);int x = m_x / (m_viewSize.width() * m_scale)* SMALL_W;int y = m_y / (m_viewSize.height() * m_scale)* SMALL_H;int wid = SMALL_W / m_scale;int hei = SMALL_H / m_scale;outPut<<"小矩形坐标及大小:"<<"("<<m_x<<" ,"<<m_y<<" ,"<<wid<<" ,"<<hei<<")";QRect rect(x,y,wid,hei);emit signalDrawRect(rect);
}stuRatio Dialog::getScalingRatio()
{stuRatio ratio;ratio.xRatio = (qreal)SMALL_W / m_viewSize.width();ratio.yRatio = (qreal)SMALL_H / m_viewSize.height();outPut<<"横纵比:"<<ratio.xRatio<<" "<<ratio.yRatio;return ratio;
}void Dialog::slot_timeout()
{QPixmap pixmap(SMALL_W,SMALL_H);pixmap.fill(Qt::transparent);QPainter painter(&pixmap);painter.setRenderHint(QPainter::Antialiasing);scene->render(&painter);pixmap.save(str,"png");dlg->setPixmap(pixmap);
}
graphicsview.h
#ifndef GRAPHICSVIEW_H
#define GRAPHICSVIEW_H
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QEvent>
#include "config.h"
//#pragma execution_characters_set("utf-8")
class GraphicsView : public QGraphicsView
{Q_OBJECT
public:GraphicsView(QWidget *parent = nullptr);GraphicsView(QGraphicsScene *scene, QWidget *parent = nullptr);
#if QT_CONFIG(wheelevent)void wheelEvent(QWheelEvent *) override;
#endifvoid setIsWheel(bool isScroll);//是否可以滚动//多边形面积qreal PolygonArea(QList<QPointF>&posList);QSize viewportSizeHint();QRect viewPortRect();void viewPortSize(QSize &size);void smallWinSize(QSize &size);
protected:bool event(QEvent *event);
// void paintEvent(QPaintEvent *event);
signals:void signalTransScale(qreal scale);void sinalCreateNavigaBar(qreal scale);//创建缩略图
public slots:void slot_MoveView(QRect rect);
//protected:
// void mouseMoveEvent(QMouseEvent *event);
// void mousePressEvent(QMouseEvent *event);
// void mouseReleaseEvent(QMouseEvent *event);
private:
// QPointF beginPoint;bool m_isScroll;//是否可以执行滚轮放大缩小事件QPointF previous_touch_point0;QPointF previous_touch_point1;int touch_status = 0;qreal m_scale;//保存缩放比qreal firstArea;//刚接触时多边形面积Config *config;qreal upLimit;//放大的上限qreal lowLimit;//缩小的下限QSize m_viewPortWH;//视口的宽高QSize m_smallWinWH;//小窗口的宽高
};
#endif // GRAPHICSVIEW_H
graphicsview.cpp
#include "graphicsview.h"
#include "log.hpp"
#include <QWheelEvent>
#include <QScrollBar>
#include <QTouchEvent>
#include <QLineF>#if QT_CONFIG(wheelevent)
void GraphicsView::wheelEvent(QWheelEvent *e)
{if(!m_isScroll){return ;}if (e->modifiers() & Qt::ControlModifier){qreal curScale = m_scale;if (e->delta() > 0)//远离{if(curScale < upLimit){m_scale *= 1.2;emit sinalCreateNavigaBar(m_scale);scale(1.2,1.2);
// m_scale *= 1.2;}}else{if(curScale > lowLimit){m_scale *= 0.8;emit sinalCreateNavigaBar(m_scale);scale(0.8,0.8);}}e->accept();}else{QGraphicsView::wheelEvent(e);}
// if(m_scale > 2)
// {emit sinalCreateNavigaBar(m_scale);
// }
// emit signalTransScale(1/m_scale);
// outPut<<"视图缩放的比例:"<<1/m_scale;
}
#endifGraphicsView::GraphicsView(QWidget *parent):QGraphicsView(parent),m_isScroll(true),touch_status(0),m_scale(1),firstArea(1)
{config = new Config();upLimit = config->Get("viewScale","upScale").toFloat();lowLimit = config->Get("viewScale","lowScale").toFloat();outPut<<"upLimit:"<<upLimit<<" "<<"lowLimit:"<<lowLimit;previous_touch_point0 = QPointF(0.0,0.0);previous_touch_point1 = QPointF(0.0,0.0);setAttribute(Qt::WA_AcceptTouchEvents);//捕获touch事件
// setRenderHint(QPainter::Antialiasing, false);setDragMode(QGraphicsView::ScrollHandDrag);setOptimizationFlags(QGraphicsView::DontSavePainterState);setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
}GraphicsView::GraphicsView(QGraphicsScene *scene, QWidget *parent):QGraphicsView(scene,parent),m_isScroll(true),touch_status(0),m_scale(1),firstArea(1)
{config = new Config();upLimit = config->Get("viewScale","upScale").toFloat();lowLimit = config->Get("viewScale","lowScale").toFloat();outPut<<"upLimit:"<<upLimit<<" "<<"lowLimit:"<<lowLimit;previous_touch_point0 = QPointF(0.0,0.0);previous_touch_point1 = QPointF(0.0,0.0);setAttribute(Qt::WA_AcceptTouchEvents);//捕获touch事件
// setRenderHint(QPainter::Antialiasing, false);setDragMode(QGraphicsView::ScrollHandDrag);setOptimizationFlags(QGraphicsView::DontSavePainterState);setViewportUpdateMode(QGraphicsView::SmartViewportUpdate);
}void GraphicsView::setIsWheel(bool isScroll)
{m_isScroll = isScroll;
}qreal GraphicsView::PolygonArea(QList<QPointF> &posList)
{QList<QPointF> tarPos;QList<QPointF> optList = posList;int nLen = posList.size();if(nLen==3){tarPos = posList;}else if(nLen>3){for(int i=0;i<optList.size()-1;++i)//按x点进行排序{for(int j=i+1;j<optList.size();++j){if(optList[j].x()<optList[i].x()){optList.swap(i,j);}}}for(int i=0;i<3-1;++i){for(int j=i+1;j<3;++j){if(optList[j].y()<optList[i].y()){optList.swap(i,j);}}tarPos.push_back(optList[i]);}tarPos.push_back(optList[2]);for(int i=3;i<optList.size()-1;++i){for(int j=i+1;j<optList.size();++j){if(optList[j].y()>optList[i].y()){optList.swap(i,j);}}tarPos.push_back(optList[i]);}tarPos.push_back(optList[optList.size()-1]);}qreal s=1;for(int k=0;k<nLen;++k){QPointF& pos1 = tarPos[k];QPointF& pos2 = tarPos[(k+1)%nLen];s +=(pos1.x()*pos2.y()-pos2.x()*pos1.y());}s=abs(0.5*s);return s;
}QSize GraphicsView::viewportSizeHint()
{return viewport()->size();
}QRect GraphicsView::viewPortRect()
{return viewport()->rect();
}void GraphicsView::viewPortSize(QSize &size)
{m_viewPortWH = size;outPut<<"视口:"<<m_viewPortWH;
}void GraphicsView::smallWinSize(QSize &size)
{m_smallWinWH = size;outPut<<"窗口:"<<m_smallWinWH;
}bool GraphicsView::event(QEvent *event)
{switch(event->type()){case QEvent::TouchBegin:{QTouchEvent* touch = static_cast<QTouchEvent*>(event);QList<QTouchEvent::TouchPoint> touchPoints = touch->touchPoints();outPut<<"TouchBegin点的个数为:"<<touchPoints.count();return true;}case QEvent::TouchUpdate:{QTouchEvent *touchEvent = static_cast<QTouchEvent *>(event);QList<QTouchEvent::TouchPoint> touchPoints = touchEvent->touchPoints();outPut<<"TouchUpdate点的个数为:"<<touchPoints.count();if (touchPoints.count() == 2 /*&& touch_status == 1*/){if(touchEvent->touchPointStates() & Qt::TouchPointPressed){const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.first();const QTouchEvent::TouchPoint &touchPoint1 = touchPoints.last();previous_touch_point0.setX(touchPoint0.pos().x());previous_touch_point0.setY(touchPoint0.pos().y());previous_touch_point1.setX(touchPoint1.pos().x());previous_touch_point1.setY(touchPoint1.pos().y());outPut<<"刚开始点:("<<previous_touch_point0.x()<<","<<previous_touch_point0.y()<<")"<<"("<<previous_touch_point1.x()<<","<<previous_touch_point1.y()<<")";touch_status=2;}if(touchEvent->touchPointStates() & Qt::TouchPointMoved){if(touch_status == 2){const QTouchEvent::TouchPoint &touchPoint0 = touchPoints.first();const QTouchEvent::TouchPoint &touchPoint1 = touchPoints.last();qreal currentScaleFactor =QLineF(touchPoint0.pos(), touchPoint1.pos()).length()/ QLineF(previous_touch_point0, previous_touch_point1).length();
// qreal proper = currentScaleFactor>1?1.05:0.8;outPut<<"起点:"<<touchPoint0.pos()<<touchPoint1.pos();outPut<<"移动后:("<<previous_touch_point0.x()<<","<<previous_touch_point0.y()<<")"<<"("<<previous_touch_point1.x()<<","<<previous_touch_point1.y()<<")";outPut<<"起点线长:"<<QLineF(touchPoint0.pos(), touchPoint1.pos()).length();outPut<<"移动后线长:"<<QLineF(previous_touch_point0, previous_touch_point1).length();outPut<<"缩放参考点为:"<<currentScaleFactor;if(currentScaleFactor > 1){if(m_scale < upLimit){scale(1.2,1.2);m_scale *= 1.2;}}else{if(m_scale > lowLimit){scale(0.8,0.8);m_scale *= 0.8;}}// scale(proper,proper);previous_touch_point0.setX(touchPoint0.pos().x());previous_touch_point0.setY(touchPoint0.pos().y());previous_touch_point1.setX(touchPoint1.pos().x());previous_touch_point1.setY(touchPoint1.pos().y());}}}if (touchPoints.count() == 3){if(touchEvent->touchPointStates() & Qt::TouchPointPressed){QList<QPointF> pointList;QPointF siglePoint;for(int i = 0; i < touchPoints.size(); ++i){siglePoint = touchPoints[i].pos();pointList.push_back(siglePoint);}firstArea = PolygonArea(pointList);touch_status = 3;}if(touchEvent->touchPointStates() & Qt::TouchPointMoved){if(touch_status == 3){QList<QPointF> pointList;QPointF siglePoint;for(int i = 0; i < touchPoints.size(); ++i){siglePoint = touchPoints[i].pos();pointList.push_back(siglePoint);}qreal lastArea = PolygonArea(pointList);qreal currentScaleFactor = lastArea / firstArea;outPut<<"刚开始面积:"<<firstArea;outPut<<"变化后面积:"<<lastArea;outPut<<"面积比:"<<currentScaleFactor;
// qreal proper = currentScaleFactor>1?1.05:0.8;
// scale(proper,proper);if(currentScaleFactor > 1){if(m_scale < upLimit){scale(1.2,1.2);m_scale *= 1.2;}}else{if(m_scale > lowLimit){scale(0.8,0.8);m_scale *= 0.8;}}firstArea = lastArea;}}}if (touchPoints.count() == 4){if(touchEvent->touchPointStates() & Qt::TouchPointPressed){QList<QPointF> pointList;QPointF siglePoint;for(int i = 0; i < touchPoints.size(); ++i){siglePoint = touchPoints[i].pos();pointList.push_back(siglePoint);}firstArea = PolygonArea(pointList);touch_status = 4;}if(touchEvent->touchPointStates() & Qt::TouchPointMoved){if(touch_status == 4){QList<QPointF> pointList;QPointF siglePoint;for(int i = 0; i < touchPoints.size(); ++i){siglePoint = touchPoints[i].pos();pointList.push_back(siglePoint);}qreal lastArea = PolygonArea(pointList);qreal currentScaleFactor = lastArea / firstArea;outPut<<"刚开始面积:"<<firstArea;outPut<<"变化后面积:"<<lastArea;outPut<<"面积比:"<<currentScaleFactor;
// qreal proper = currentScaleFactor>1?1.05:0.8;
// scale(proper,proper);if(currentScaleFactor > 1){if(m_scale < upLimit){scale(1.2,1.2);m_scale *= 1.2;}}else{if(m_scale > lowLimit){scale(0.8,0.8);m_scale *= 0.8;}}firstArea = lastArea;}}}if (touchPoints.count() == 5){if(touchEvent->touchPointStates() & Qt::TouchPointPressed){QList<QPointF> pointList;QPointF siglePoint;for(int i = 0; i < touchPoints.size(); ++i){siglePoint = touchPoints[i].pos();pointList.push_back(siglePoint);}firstArea = PolygonArea(pointList);touch_status = 5;}if(touchEvent->touchPointStates() & Qt::TouchPointMoved){if(touch_status == 5){QList<QPointF> pointList;QPointF siglePoint;for(int i = 0; i < touchPoints.size(); ++i){siglePoint = touchPoints[i].pos();pointList.push_back(siglePoint);}qreal lastArea = PolygonArea(pointList);qreal currentScaleFactor = lastArea / firstArea;outPut<<"刚开始面积:"<<firstArea;outPut<<"变化后面积:"<<lastArea;outPut<<"面积比:"<<currentScaleFactor;
// qreal proper = currentScaleFactor>1?1.05:0.8;
// scale(proper,proper);if(currentScaleFactor > 1){if(m_scale < upLimit){scale(1.2,1.2);m_scale *= 1.2;}}else{if(m_scale > lowLimit){scale(0.8,0.8);m_scale *= 0.8;}}firstArea = lastArea;}}}else if(touchEvent->touchPointStates() & Qt::TouchPointReleased){touch_status=0;}event->accept();return true;}case QEvent::TouchEnd:{event->accept();return true;}default:break;}return QGraphicsView::event(event);//QWidget::event(event);
}void GraphicsView::slot_MoveView(QRect rect)
{verticalScrollBar()->setValue(rect.y()*m_scale*m_viewPortWH.height()/m_smallWinWH.height());horizontalScrollBar()->setValue(rect.x()*m_scale*m_viewPortWH.width()/m_smallWinWH.width());
}//void GraphicsView::mouseMoveEvent(QMouseEvent *event)
//{
// if(event->buttons() & Qt::LeftButton)
// {
// QPointF pos = event->screenPos();
// qreal x = pos.x() - beginPoint.x();
// qreal y = pos.y() - beginPoint.y();// QScrollBar* verBar = verticalScrollBar();
// int nValue = verBar->value();
// verBar->setValue(nValue - y);// QScrollBar* horBar = horizontalScrollBar();
// nValue = horBar->value();
// horBar->setValue(nValue - x);
// }
// QGraphicsView::mouseMoveEvent(event);
//}//void GraphicsView::mousePressEvent(QMouseEvent *event)
//{
// if(event->button() == Qt::LeftButton)
// {
// beginPoint = event->screenPos();
// }
// QGraphicsView::mousePressEvent(event);
//}//void GraphicsView::mouseReleaseEvent(QMouseEvent *event)
//{
// QGraphicsView::mouseReleaseEvent(event);
//}
MyGraphicsScene.h
#pragma once//#include <vld.h>
#include <QGraphicsScene>class MyGraphicsScene : public QGraphicsScene
{Q_OBJECTpublic:MyGraphicsScene(QObject *parent = nullptr);virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent);virtual void mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent);virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent);Q_SIGNALS:void previewRectMoved(QRect rect);public Q_SLOTS:void onSetPreviewRect(QRect rect);private:QGraphicsRectItem* m_pRectItem;QRect m_rectSaved;bool m_bRectClicked;QPoint m_ptRectRelated; // 鼠标点击时,相对于红色矩形框的位置
};
MyGraphicsScene.cpp
#include "MyGraphicsScene.h"
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsRectItem>
#include <QDebug>MyGraphicsScene::MyGraphicsScene(QObject *parent): QGraphicsScene(parent), m_bRectClicked(false)
{m_pRectItem = new QGraphicsRectItem(0, 0, 0, 0);QPen penRectItem = QPen(QColor(255, 0, 0));penRectItem.setWidth(2);m_pRectItem->setPen(penRectItem);m_pRectItem->setZValue(1);addItem(m_pRectItem);
}void MyGraphicsScene::onSetPreviewRect(QRect rect)
{m_rectSaved = rect;// 内缩几个像素,用矩形外边框来标示viewport显示区域m_pRectItem->setRect(rect.x() -2/*+ 5*/, rect.y() - 2/*+ 5*/, rect.width() - 4, rect.height() - 4);
}void MyGraphicsScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{QGraphicsScene::mouseMoveEvent(mouseEvent);if (m_bRectClicked) {QPoint ptTopLeft = mouseEvent->scenePos().toPoint() - m_ptRectRelated;m_rectSaved.setTopLeft(ptTopLeft);emit previewRectMoved(m_rectSaved);}
}void MyGraphicsScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{QGraphicsScene::mousePressEvent(mouseEvent);if (m_rectSaved.contains(mouseEvent->scenePos().x(), mouseEvent->scenePos().y())) {m_bRectClicked = true;m_ptRectRelated = mouseEvent->scenePos().toPoint() - m_rectSaved.topLeft();}
}void MyGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
{QGraphicsScene::mouseReleaseEvent(mouseEvent);m_bRectClicked = false;
}
所有程序的代码上面已经全部贴出,由于还涉及到ui文件,所以要看运行效果,需先创建基于对话框QDialog的程序,在此基础上修改添加创建对应的文件,另外还需注意,修改你本地的视频所在路径,并将配置文件拷贝到可执行目录下,qt可能还不能直接运行,因为缺少解码器,这时根据提示下载安装解码器,解决掉“那个”问题之后便可以运行,查看相应的效果。
注意:
- 修改需要你需要播放的视频的路径,重新指定需要播放的视频;
- 将下面的配置文件拷贝到可执行目录下。
Config.ini
[viewScale]
upScale = 3
lowScale = 0.3