移动场景在其缩略图中显示场景中所显示的区域

需求描述

在场景中实现拖动,缩放,并在场景的缩略图中显示其对应在视口中显示的矩形区域。
程序效果图如下:
在这里插入图片描述
开发环境: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可能还不能直接运行,因为缺少解码器,这时根据提示下载安装解码器,解决掉“那个”问题之后便可以运行,查看相应的效果。
注意:

  1. 修改需要你需要播放的视频的路径,重新指定需要播放的视频;
  2. 将下面的配置文件拷贝到可执行目录下。
    Config.ini

[viewScale]
upScale = 3
lowScale = 0.3

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/524235.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

那些中国式家庭的小烦恼,我看用AI来解决就“都挺好” | 技术头条

戳蓝字“CSDN云计算”关注我们哦&#xff01;技术头条&#xff1a;干货、简洁、多维全面。更多云计算精华知识尽在眼前&#xff0c;get要点、solve难题&#xff0c;统统不在话下&#xff01;转自&#xff1a;趣味科技v今天&#xff0c;又是《都挺好》全面承包热搜的一天。自从这…

penGL ES 2.0 和 3.0区别

目录 一.嵌入式设备的 OpenGL ES 版本二.兼容性三.着色器脚本 1.OpenGL ES shader 2.02.OpenGL ES shader 3.03.版本声明4. 默认精度修饰符 precision4.输入输出5.变量赋值 四.关于顶点缓冲区对象 VBO 与顶点数组对象 VAO五.PBO六.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : O…

使用thymeleaf的时候报元素类型“meta“必须由匹配的结束标记

使用thymeleaf的时候报元素类型"meta"必须由匹配的结束标记""终止> 解决方案有二种&#xff1a; 第一种&#xff1a; 让html的标记严格严谨的语法&#xff1a; 加上结束标签第一种&#xff1a;&#xff1a;修改thymeleaf版本 <thymeleaf.version…

漫话:如何给女朋友解释什么是系统可用性? | 技术头条

戳蓝字“CSDN云计算”关注我们哦&#xff01;技术头条&#xff1a;干货、简洁、多维全面。更多云计算精华知识尽在眼前&#xff0c;get要点、solve难题&#xff0c;统统不在话下&#xff01;转自&#xff1a;漫话编程在一个阳光明媚的周二下午&#xff0c;我正在公司里面看着即…

基于websocket的简单通信

首次接触websocket通信协议&#xff0c;不足之处希望指出一起进步。 简述 websocket是基于tcp协议的一种网络通信协议&#xff0c;分为客户端和服务端&#xff0c;可以实现客户端与服务端的双向通信。 与tcp的不同之处是&#xff1a; 1.客户端与服务端只需要一次握手协议&…

OpenGL ES 名词解释(一)

目录 一.前言二.OpenGL ES 上下文三.OpenGL ES 状态机四.缓存五.渲染六.纹理七.光栅化 Rasterization八.片元着色器九.顶点着色器十.着⾊语言 GLSL十一.着色器使用流程十二.着色器的渲染流程十三.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenG…

大龄程序员失业后,看他们是如何破局突围的? | 技术头条

戳蓝字“CSDN云计算”关注我们哦&#xff01;技术头条&#xff1a;干货、简洁、多维全面。更多云计算精华知识尽在眼前&#xff0c;get要点、solve难题&#xff0c;统统不在话下&#xff01;作者&#xff1a;逆流的鱼yuiop转自&#xff1a;何俊林王小波在《黄金时代》里写道&am…

分布式架构系列: 负载均衡技术详解 | 技术头条

戳蓝字“CSDN云计算”关注我们哦&#xff01;技术头条&#xff1a;干货、简洁、多维全面。更多云计算精华知识尽在眼前&#xff0c;get要点、solve难题&#xff0c;统统不在话下&#xff01;作者&#xff1a;ITFLY8转自&#xff1a;架构师技术联盟面对大量用户访问、高并发请求…

第七篇:Spring Boot整合Thymeleaf_入门试炼03

基本语法实战案例01 在ThymeleafController中添加此方法 RequestMapping("/show5")public String showInfo5(Model model) {model.addAttribute("msg", "Thymeleaf 第一个案例");model.addAttribute("key", new Date());return &quo…

Qt下自适应分辨率

qt下自适应分辨率应该有两种方法&#xff1a;通过栅格布局&#xff1b;通过缩放比。 本人采用的是缩放比来适应不同的分辨率。首先定义一个类实现屏幕分辨率和长宽缩放比的获取&#xff0c;由于该类可能被多个ui界面使用&#xff0c;所以定义为一个单例模式。代码如下&#xff…

OpenGL ES EGL 简介

目录 一.EGL 简介二.EGL 跨平台之 ANGLE 1.ANGLE 支持跨平台2.ANGLE 支持渲染器3.ANGLE 下载地址 三.EGL 坐标系四.EGL 绘图步骤五.猜你喜欢 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录 >> OpenGL ES 基础 零基础 OpenGL ES 学习路线推荐 : OpenGL ES 学习目录…

第八篇:Spring Boot整合Thymeleaf_入门试炼04

继承parent父工程&#xff0c;新建一个子项目&#xff0c;名称为spring-boot-chapter-8 1、引入 thymeleaf 模板依赖 <!-- 引入 thymeleaf 模板依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-star…

华为发布基于第二代英特尔®至强®可扩展处理器家族的新一代服务器

2019年4月4日&#xff0c;在主题为“智能&#xff0c;计算进化”的发布会上&#xff0c;华为正式发布了基于第二代英特尔 至强 可扩展处理器以及支持英特尔傲腾 ™ 数据中心级持久内存的新一代FusionServerPro智能服务器&#xff0c;包括2路、4路机架式服务器&#xff0c;高密X…

java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä'

java.sql.SQLException: The server time zone value ‘’ is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver (via the serverTimezone configuration property) to use a more specifc time zone value if you w…

第九篇:Spring Boot整合Spring Data JPA_入门试炼01

Spring Data JPA:介绍&#xff1a; Spring Data就是spring提供操作数据库的框架&#xff0c;而Spring Data JPA只是Spring Data框架下的一个基于JPA标准操作数据库的模块。 Spring Data JPA&#xff1a;基于JPA的标准对数据进行操作。简化持久层的代码&#xff0c;只需要写接口…

华为智能计算发布FusionServer Pro智能服务器

【中国&#xff0c;北京&#xff0c;2019年4月3日】华为智能计算业务部在北京召开了主题为“智能&#xff0c;计算进化”的发布会&#xff0c;正式发布FusionServer Pro智能服务器。将从“智能加速、智能管理、智能数据中心”三个层次助力数据中心智能化升级。 世界正从数字化…

分布式精华问答:分布式环境下如何保持数据一致性的?| 技术头条

分布式开发的时代实际上早已悄悄地成为了时代的主流&#xff0c;今天&#xff0c;我们就来看看关于分布式的精华问答吧&#xff01;1Q&#xff1a;分布式系统中主要是用到了服务化&#xff0c;消息中间件&#xff0c;数据库拆分&#xff0c;便于横向扩展和维护&#xff0c;但分…

第九篇:Spring Boot整合Spring Data JPA_入门试炼03

CrudRepository接口的使用 CrudRepository接口&#xff0c;主要完成一些增删改查的操作。 注意&#xff1a;CrudRepository接口继承Repository接口 1、持久层接口&#xff1a; package com.gblfy.repository;import com.gblfy.pojo.Users; import org.springframework.data.r…

第九篇:Spring Boot整合Spring Data JPA_入门试炼04

六、PagingAndSortingRepository接口 前言&#xff1a;该接口提供了分页与排序的操作&#xff0c;该接口继承了CrudRepository 1、持久层接口&#xff1a; public interface UserRepositoryPagingAndSorting extends PagingAndSortingRepository<Users,Integer> { }测试…

成立一周?谷歌人工智能道德委员会解散了?近日,金山云和小米刚签订了不超过9000万的硬件产品供应协议,闹哪样? | 极客头条...

关注并标星星CSDN云计算极客头条&#xff1a;速递、最新、绝对有料。这里有企业新动、这里有业界要闻&#xff0c;打起十二分精神&#xff0c;紧跟fashion你可以的&#xff01;每周三次&#xff0c;打卡即read更快、更全了解泛云圈精彩newsgo go go 亚马逊推Alexa无线耳机&…