日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【Qt】2D绘图之图形视图框架(一)

發布時間:2024/4/24 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Qt】2D绘图之图形视图框架(一) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

00. 目錄

文章目錄

    • 00. 目錄
    • 01. 概述
    • 02. 開發環境
    • 03. 場景(Scene)
    • 04. 視圖(View)
    • 05. 圖形項
    • 06. 附錄

01. 概述

在前面講的基本繪圖中,我們可以自己繪制各種圖形,并且控制它們。但是,如果需要同時繪制很多個相同或不同的圖形,并且要控制它們的移動、檢測它們的碰撞和疊加;或者我們想讓自己繪制的圖形可以拖動位置、進行縮放和旋轉等操作。實現這些功能,要是還使用以前的方法,那么會十分困難。解決這些問題,可以使用Qt提供的圖形視圖框架。

圖形視圖(Graphics View)框架結構的主要特點如下:

  • 圖形視圖(Graphics View)可以對大量定制的2D圖形項進行管理和相互作用。視圖部件可以讓所有圖形項可視化,它還提供了縮放和旋轉功能。
  • 框架中包含了一個事件傳播構架,提供了和場景中的圖形項進行精確的雙精度交互的能力,圖形項可以處理鍵盤事件,鼠標的按下、移動、釋放和雙擊事件,還可以跟蹤鼠標的移動。
  • 圖形視圖框架使用一個BSP(Binary Space Partitioning)樹來快速發現圖形項,也正是因為如此,它可以實時顯示一個巨大的場景,甚至包含上百萬個圖形項。
  • 圖形視圖框架結構中,系統可以利用Qt繪圖系統的反鋸齒、OpenGL工具來改善繪圖性能。

圖形視圖結構主要包含三部分:

  • 場景(Scene) :QGraphicsScene類
  • 視圖(View) :QGraphicsView類
  • 圖形項(Item):QGraphicsItem類

02. 開發環境

Windows系統:Windows10

Qt版本:Qt5.15或者Qt6

03. 場景(Scene)

場景是圖形項QGraphicsItem對象的容器,其主要完成的工作包括:

(1)提供用于管理大量圖形項的快速接口;

(2)傳播事件給每一個圖形項;

(3)管理圖形項的狀態(如選擇和焦點處理);

(4)提供無變換的渲染功能,主要用于打印。

下面是一些QGraphicsScene的常用函數:

  • 可以調用QGraphicsScene: :addItem()函數將圖形項添加到場景中,然后調用任意一個圖形項發現函數來檢索添加的圖形項。
  • QGraphicsScene::items()函數和其他幾個重載函數可以返回符合條件的所有圖形項。這些圖形項不是與指定的點、矩形、多邊形或者矢量路徑相交,就是包含在它們之中。
  • QGraphicsScene::itemAt()函數返回指定點的最上面的圖形項。所有的圖形項發現函數返回的圖形項都是使用遞減順序(例如第一個返回的圖形項在最上面,最后返回的圖形項在最下面)。
  • 如果要從場景中刪除一個圖形項,可以使用QGraphicsScene::Removeltem()函數。
  • 可以通過向QGraphicsScene::setSelectionArea()函數中傳遞一個任意的形狀來選擇場景中指定的圖形項。
  • 如果要獲取當前選取的所有圖形項的列表,可以使用QGraphicsScene:: selectedltems()函數。
  • 另外可以調用QGraphicsScene:: setFocusItem()或者 QGraph-icsScene:: setFocus( )函數來為一個圖形項設置焦點,調用QGraphicsScene:: focusItem()函數來獲取當前獲得焦點的圖形項。
  • QGraphicsScene:: render()函數將場景中的一部分渲染到一個繪圖設備上。

下面先來看一個最簡單的例子。新建空的Qt項目(Empty qmake Project),項目名稱為myscene。然后在這個項目中添加新的C++源文件,命名為main.cpp。添加完成后首先在myscene.pro文件中添加一行代碼:

QT += widgets

然后將main.cpp的內容更改如下。

#include <QApplication> #include <QGraphicsScene> #include <QGraphicsRectItem> #include <QDebug>int main(int argc, char **argv) {QApplication app(argc, argv);//新建場景QGraphicsScene scene;//創建矩形圖形項QGraphicsRectItem *item = new QGraphicsRectItem(0, 0, 100, 100);//將圖形項添加到場景中scene.addItem(item);//輸出(50, 50)點處的圖形項qDebug() << scene.itemAt(50, 50, QTransform());return app.exec(); }

這里先創建了一個場景,然后創建了一個矩形圖形項,并且將該圖形項添加到了場景中。然后使用itemAt()函數來返回指定坐標處最頂層的圖形項,這里返回的就是剛才添加的矩形圖形項。現在可以運行程序,不過因為還沒有設置視圖,所以不會出現任何圖形界面,這時可以在應用程序輸出欄中看到輸出的項目的信息如下:

QGraphicsItem(0x18a8720, pos=0,0)

04. 視圖(View)

QGraphicsView提供了視圖部件,它用來使場景中的內容可視化??梢赃B接多個視圖到同一個場景來為相同的數據集提供多個視口。

下面是一些QGraphicsView:的常用函數:

  • 視圖部件是一個可滾動的區域,提供了一個滾動條來瀏覽大的場景,可以使用setDragMode()函數以QGraphicsView::SCrollHandDrag為參數來使光標變為手掌形狀,從而可以拖動場景。
  • 如果設置 setDragMode()的參數為QGraphicsView::RubberBandDrag,那么可以在視圖上使用 鼠標拖出橡皮筋框來選擇圖形項。
  • 默認的QGraphicsView提供了一個QWidget作為視口部件,如果要使用OpenGL進行植染,可以調用QGraphicsView::setViewport()設置QOpenGLWidget作為視口。QGraphicsView會獲取視口部件的擁有權(ownership)。

在前面的程序中先添加頭文件# include ,然后main.cpp文件中的代碼:

#include <QApplication> #include <QGraphicsScene> #include <QGraphicsView> #include <QGraphicsRectItem> #include <QDebug>int main(int argc, char **argv) {QApplication app(argc, argv);//新建場景QGraphicsScene scene;//創建矩形圖形項QGraphicsRectItem *item = new QGraphicsRectItem(0, 0, 100, 100);//將圖形項添加到場景中scene.addItem(item);//輸出(50, 50)點處的圖形項qDebug() << scene.itemAt(50, 50, QTransform());//創建視圖QGraphicsView view(&scene);//設置場景的前景色view.setForegroundBrush(QColor(255, 255, 0, 100));//設置場景的背景圖片view.setBackgroundBrush(QPixmap(":/image/d.png"));view.resize(400, 300);view.show();return app.exec(); }

這里新建了視圖部件,并指定了要可視化的場景。然后為該視圖設置了場景前景色和背景圖片。一個場景分為3層:圖形項層(ItemLayer)、前景層(ForegroundLayer)和背景層(BackgroundLayer)。場景的繪制總是從背景層開始,然后是圖形項層,最后是前景層。前景層和背景層都可以使用QBrush進行填充,比如使用漸變和貼圖等。這里的前景色設置為半透明的黃色,當然也可以設置為其他的填充。這里要提示一下,其實使用好前景色可以實現很多特殊的效果,比如使用半透明的黑色便可以實現夜幕降臨的效果。

代碼中使用了 QGraphicsView類中的函數來設置場景中的背景和前景,其實也可以使用QGraphicsScene中的同名函數來實現,不過它們的效果并不完全 一樣。如果使用QGraphicsScene對象設置了場景背景或者前景,那么對所有關聯了該場景的視圖都有效,而QGraphicsView對象設置的場景的背景或者前景,只對它本身對應的視圖有效。

運行程序,效果如下圖所示。可以看到矩形圖形項和背景圖片都是在視圖中間部分進行繪制的,這個問題會在后面的坐標系統部分詳細講解。

05. 圖形項

QGraphicsItem是場景中圖形項的基類。圖形視圖框架為典型的形狀提供了標準的圖形項,比如矩形(QGraphicsRectlem)、橢圓(QGraphicsEllipseltem)和文本項(QGraphicsTextltem)。不過,只有編寫自定義的圖形項時才能發揮QGraphicsItem的強大功能。

QGraphicsItem主要支持以下功能:

  • 鼠標按下、移動、釋放、雙擊、懸停、滾輪和右鍵菜單事件;
  • 鍵盤輸入焦點和鍵盤事件;
  • 拖放事件;
  • 分組,使用QGraphicsItemGroup通過parent-child關系來實現;
  • 碰撞檢測。

除此之外,圖形項還可以存儲自定義的數據,可以使用setData()進行數據存儲,然后使用data()獲取其中的數據。下面自定義圖形項。

在前面的程序中添加新文件,模板選擇C+ +類,類名為Myltem,基類為 QGraphicsItem,類型信息選擇“無”。添加完成后,在myitem.h文件中添加兩個函數的聲明:

#ifndef MYITEM_H #define MYITEM_H#include <QGraphicsItem>class MyItem : public QGraphicsItem { public:MyItem();//返回要繪制圖形項的矩形區域QRectF boundingRect() const;//用來執行實際的繪圖操作void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget); };#endif // MYITEM_H

再到myitem.cpp文件中添加頭文件# include ,然后定義添加的兩個函數:

#include "myitem.h"#include <QPainter>MyItem::MyItem() {}//返回要繪制圖形項的矩形區域 QRectF MyItem::boundingRect() const {qreal penWidth = 1;return QRectF(0 - penWidth / 2, 0 - penWidth / 2,20 + penWidth, 20 + penWidth); }//用來執行實際的繪圖操作 void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) {//聲明參數沒有使用Q_UNUSED(option);Q_UNUSED(widget);painter->setBrush(Qt::red);painter->drawRect(0, 0, 20, 20); }

要實現自定義的圖形項,那么首先要創建一個QGraphicsItem的子類,然后重新實現它的兩個純虛公共函數:boimdingRect()和paint(),前者用來返回要繪制圖形項的矩形區域,后者用來執行實際的繪圖操作。其中,boimdingRect()函數將圖形項的外部邊界定義為一個矩形,所有的繪圖操作都必須限制在圖形項的邊界矩形之中。而且,QGraphicsView要使用這個矩形來剔除那些不可見的圖形項,另外QGraphicsItem的碰撞檢測機制也需要使用到這個邊界矩形。

下面到main.cpp中添加#include “myitem.h”,將程序改為:

#include <QApplication> #include <QGraphicsScene> #include <QGraphicsView> #include <QGraphicsRectItem> #include <QDebug> #include "myitem.h"int main(int argc, char **argv) {QApplication app(argc, argv);//新建場景QGraphicsScene scene;//創建矩形圖形項//QGraphicsRectItem *item = new QGraphicsRectItem(0, 0, 100, 100);MyItem *item = new MyItem;//將圖形項添加到場景中scene.addItem(item);//輸出(50, 50)點處的圖形項qDebug() << scene.itemAt(50, 50, QTransform());//創建視圖QGraphicsView view(&scene);//設置場景的前景色view.setForegroundBrush(QColor(255, 255, 0, 100));//設置場景的背景圖片view.setBackgroundBrush(QPixmap(":/image/d.png"));view.resize(400, 300);view.show();return app.exec(); }

這時運行程序,效果如下圖所示。可以看到,自定義的紅色小方塊出現在了視圖的正中間,背景圖片的位置也有所變化,這些問題都會在后面的坐標系統中講到。如果只想添加簡單的圖形項,那么也可以直接使用圖形視圖框架提供的8種標準圖形項。

圖形視圖框架提供的標準圖形項

06. 附錄

源碼下載:【Qt】2D繪圖之圖形視圖框架(一).rar

總結

以上是生活随笔為你收集整理的【Qt】2D绘图之图形视图框架(一)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。