国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Qt5開發(fā)及實(shí)例V2.0-第七章-Qt圖形視圖框架

這篇具有很好參考價(jià)值的文章主要介紹了Qt5開發(fā)及實(shí)例V2.0-第七章-Qt圖形視圖框架。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

第7章 Qt 5圖形視圖框架

7.1 圖形視圖體系結(jié)構(gòu)

7.1.1 Graphics View的特點(diǎn)

Graphics View框架結(jié)構(gòu)的主要特點(diǎn)如下。
(1)Graphics View框架結(jié)構(gòu)中,系統(tǒng)可以利用Qt繪圖系統(tǒng)的反鋸齒、OpenGL工具來改善繪圖性能。
(2)Graphics View支持事件傳播體系結(jié)構(gòu),可以使圖元在場(chǎng)景(scene)中的交互能力提高1倍,圖元能夠處理鍵盤事件和鼠標(biāo)事件。其中,鼠標(biāo)事件包括鼠標(biāo)按下、移動(dòng)、釋放和雙擊,還可以跟蹤鼠標(biāo)的移動(dòng)。
(3)在Graphics View框架中,通過二元空間劃分樹(Binary Space Partitioning,BSP)提供快速的圖元查找,這樣就能夠?qū)崟r(shí)地顯示包含上百萬(wàn)個(gè)圖元的大場(chǎng)景。

7.1.2 Graphics View的三元素

它們?nèi)咧g的關(guān)系如圖7.1所示。
Qt5開發(fā)及實(shí)例V2.0-第七章-Qt圖形視圖框架,QT5,ARM?MCU,Linux,qt,數(shù)據(jù)庫(kù),服務(wù)器,開發(fā)語(yǔ)言,運(yùn)維,linux

1.場(chǎng)景類:QGraphicsScene類
場(chǎng)景類主要完成的工作包括提供對(duì)它包含的圖元的操作接口和傳遞事件、管理各個(gè)圖元的狀態(tài)(如選擇和焦點(diǎn)處理)、提供無變換的繪制功能(如打?。┑取?br> 事件傳播體系結(jié)構(gòu)將場(chǎng)景事件發(fā)送給圖元,同時(shí)也管理圖元之間的事件傳播。如果場(chǎng)景接收到了在某一點(diǎn)的鼠標(biāo)單擊事件,場(chǎng)景會(huì)將事件傳給這一點(diǎn)的圖元。
管理各個(gè)圖元的狀態(tài)(如選擇和焦點(diǎn)處理)??梢酝ㄟ^QGraphicsScene:: setSelectionArea()函數(shù)選擇圖元,選擇區(qū)域可以是任意的形狀,使用QPainterPath表示。若要得到當(dāng)前選擇的圖元列表,則可以使用函數(shù)QGraphicsScene:: selectedItems()??梢酝ㄟ^QGraphicsScene:: setFocusItem()函數(shù)或QGraphicsScene:: setFocus()函數(shù)來設(shè)置圖元的焦點(diǎn),獲得當(dāng)前具有焦點(diǎn)的圖元使用函數(shù)QGraphicsScene::focusItem()。

2.視圖類:QGraphicsView類
QGraphicsView是可滾動(dòng)的窗口部件,可以提供滾動(dòng)條來瀏覽大的場(chǎng)景。如果需要使用OpenGL,則可以使用QGraphicsView::setViewport()將視圖設(shè)置為QGLWidget。
視圖接收鍵盤和鼠標(biāo)的輸入事件,并將它們翻譯為場(chǎng)景事件(將坐標(biāo)轉(zhuǎn)換為場(chǎng)景的坐標(biāo))。使用變換矩陣函數(shù)QGraphicsView::matrix()可以變換場(chǎng)景的坐標(biāo),實(shí)現(xiàn)場(chǎng)景縮放和旋轉(zhuǎn)。QGraphicsView提供QGraphicsView::mapToScene()和QGraphicsView:: mapFromScene()用于與場(chǎng)景的坐標(biāo)進(jìn)行轉(zhuǎn)換。

3.圖元類:QGraphicsItem類
它是場(chǎng)景中各個(gè)圖元的基類,在它的基礎(chǔ)上可以繼承出各種圖元類,Qt已經(jīng)預(yù)置的包括直線(QGraphicsLineItem)、橢圓(QGraphicsEllipseItem)、文本圖元(QGraphicsTextItem)、矩形(QGraphicsRectItem)等。
QGraphicsItem主要有以下功能。
? 處理鼠標(biāo)按下、移動(dòng)、釋放、雙擊、懸停、滾輪和右鍵菜單事件。
? 處理鍵盤輸入事件。
? 處理拖曳事件。
? 分組。
? 碰撞檢測(cè)。

7.1.3 GraphicsView的坐標(biāo)系統(tǒng)

1.場(chǎng)景坐標(biāo)
場(chǎng)景坐標(biāo)是所有圖元的基礎(chǔ)坐標(biāo)系統(tǒng)。場(chǎng)景坐標(biāo)系統(tǒng)描述了頂層的圖元,每個(gè)圖元都有場(chǎng)景坐標(biāo)和相應(yīng)的包容框。場(chǎng)景坐標(biāo)的原點(diǎn)在場(chǎng)景中心,坐標(biāo)原點(diǎn)是x軸正方向向右,y軸正方向向下。
QGraphicsScene類的坐標(biāo)系以中心為原點(diǎn)(0,0),如圖7.2所示。
Qt5開發(fā)及實(shí)例V2.0-第七章-Qt圖形視圖框架,QT5,ARM?MCU,Linux,qt,數(shù)據(jù)庫(kù),服務(wù)器,開發(fā)語(yǔ)言,運(yùn)維,linux

2.視圖坐標(biāo)
視圖坐標(biāo)是窗口部件的坐標(biāo)。視圖坐標(biāo)的單位是像素。QGraphicsView視圖的左上角是(0,0),x軸正方向向右,y軸正方向向下。所有的鼠標(biāo)事件最開始都是使用視圖坐標(biāo)。
QGraphicsView類繼承自QWidget類,因此它與其他的QWidget類一樣,以窗口的左上角作為自己坐標(biāo)系的原點(diǎn),如圖7.3所示。
Qt5開發(fā)及實(shí)例V2.0-第七章-Qt圖形視圖框架,QT5,ARM?MCU,Linux,qt,數(shù)據(jù)庫(kù),服務(wù)器,開發(fā)語(yǔ)言,運(yùn)維,linux

3.圖元坐標(biāo)
圖元使用自己的本地坐標(biāo),這個(gè)坐標(biāo)系統(tǒng)通常以圖元中心為原點(diǎn),這也是所有變換的原點(diǎn)。圖元坐標(biāo)方向是x軸正方向向右,y軸正方向向下。創(chuàng)建圖元后,只需注意圖元坐標(biāo)就可以了,QGraphicsScene和QGraphicsView會(huì)完成所有的變換。
QGraphicsItem類的坐標(biāo)系,若在調(diào)用QGraphicsItem類的paint()函數(shù)重繪圖元時(shí),則以此坐標(biāo)系為基準(zhǔn),如圖7.4所示。
Qt5開發(fā)及實(shí)例V2.0-第七章-Qt圖形視圖框架,QT5,ARM?MCU,Linux,qt,數(shù)據(jù)庫(kù),服務(wù)器,開發(fā)語(yǔ)言,運(yùn)維,linux
Graphics View框架提供了多種坐標(biāo)變換函數(shù),見表7.1。
Qt5開發(fā)及實(shí)例V2.0-第七章-Qt圖形視圖框架,QT5,ARM?MCU,Linux,qt,數(shù)據(jù)庫(kù),服務(wù)器,開發(fā)語(yǔ)言,運(yùn)維,linux

7.2 【實(shí)例】:圖形視圖

7.2.1 飛舞的蝴蝶

【例】(難度中等)(CH701)設(shè)計(jì)界面,一個(gè)蝴蝶在屏幕上不停地上下飛舞。
操作步驟如下。
(1)新建Qt Widgets Application(詳見1.3.1節(jié)),項(xiàng)目名為“Butterfly”,基類選擇“QMainWindow”,類名命名默認(rèn)為“MainWindow”,取消“創(chuàng)建界面”復(fù)選框的選中狀態(tài)。單擊“下一步”按鈕,最后單擊“完成”按鈕,完成該項(xiàng)目工程的建立。
(2)在“Butterfly”項(xiàng)目名上單擊鼠標(biāo)右鍵,在彈出的快捷菜單中選擇“添加新文件…”菜單項(xiàng),在彈出的對(duì)話框中選擇“C++ Class”選項(xiàng)。單擊“Choose…”按鈕,彈出對(duì)話框,在“Base class”后面的下拉列表框中選擇基類名“QObject”,在“Class name”后面的文本框中輸入類的名稱“Butterfly”。
(3)單擊“下一步”按鈕,單擊“完成”按鈕,添加文件“butterfly.h”和“butterfly. cpp”。

(4)Butterfly類繼承自QObject類、QGraphicsItem類,在頭文件“butterfly.h”中完成的代碼具體內(nèi)容。
(5)在源文件“butterfly. cpp”中完成的代碼具體內(nèi)容如下:

#include "butterfly.h"
#include <math.h>
const static double PI=3.1416;
Butterfly::Butterfly(QObject *parent) : QObject(parent)
{
    up = true;			//給標(biāo)志蝴蝶翅膀位置的變量賦初值
    pix_up.load("up.png");		//調(diào)用QPixmap的load()函數(shù)加載所用到的圖片
    pix_down.load("down.png");
    startTimer(100);		//啟動(dòng)定時(shí)器,并設(shè)置時(shí)間間隔為100毫秒
}

boundingRect()函數(shù)為圖元限定區(qū)域范圍。此范圍是以圖元自身的坐標(biāo)系為基礎(chǔ)設(shè)定的。具體實(shí)現(xiàn)代碼內(nèi)容如下:

QRectF Butterfly::boundingRect() const
{
    qreal adjust =2;
    return QRectF(-pix_up.width()/2-adjust,-pix_up.height()/2-adjust,
                  pix_up.width()+adjust*2,pix_up.height()+adjust*2);
}

在重畫函數(shù)paint()中,首先判斷當(dāng)前已顯示的圖片是pix_up還是pix_down。實(shí)現(xiàn)蝴蝶翅膀上下飛舞效果時(shí),若當(dāng)前顯示的是pix_up圖片,則重繪pix_down圖片,反之亦然。具體實(shí)現(xiàn)代碼內(nèi)容如下:

void Butterfly::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    if(up)
    {
        painter->drawPixmap(boundingRect().topLeft(),pix_up);
        up=!up;
    }
    else
    {
        painter->drawPixmap(boundingRect().topLeft(),pix_down);
        up=!up;
    }
}

定時(shí)器的timerEvent()函數(shù)實(shí)現(xiàn)蝴蝶的飛舞,具體實(shí)現(xiàn)代碼內(nèi)容如下:

void Butterfly::timerEvent(QTimerEvent *)
{
    //邊界控制
    qreal edgex=scene()->sceneRect().right()+boundingRect().width()/2;
					//限定蝴蝶飛舞的右邊界
    qreal edgetop=scene()->sceneRect().top()+boundingRect(). height()/2;							//限定蝴蝶飛舞的上邊界
    qreal edgebottom=scene()->sceneRect().bottom()+boundingRect(). height()/2;				//限定蝴蝶飛舞的下邊界
    if(pos().x()>=edgex)			//若超過了右邊界,則水平移回左邊界處
        setPos(scene()->sceneRect().left(),pos().y());
    if(pos().y()<=edgetop)			//若超過了上邊界,則垂直移回下邊界處
        setPos(pos().x(),scene()->sceneRect().bottom());
    if(pos().y()>=edgebottom)		//若超過了下邊界,則垂直移回上邊界處
        setPos(pos().x(),scene()->sceneRect().top());
    angle+=(qrand()%10)/20.0;
    qreal dx=fabs(sin(angle*PI)*10.0);
    qreal dy=(qrand()%20)-10.0;
    setPos(mapToParent(dx,dy));		//(a)
}

(6)完成了蝴蝶圖元的實(shí)現(xiàn)后,在源文件“main.cpp”中將它加載到場(chǎng)景中,并關(guān)聯(lián)一個(gè)視圖,具體實(shí)現(xiàn)代碼內(nèi)容如下:

#include <QApplication>
#include "butterfly.h"
#include <QGraphicsScene>
int main(int argc,char* argv[])
{
    QApplication a(argc,argv);
    QGraphicsScene *scene = new QGraphicsScene;
    scene->setSceneRect(QRectF(-200,-200,400,400));
    Butterfly *butterfly = new Butterfly;
    butterfly->setPos(-100,0);
    scene->addItem(butterfly);
    QGraphicsView *view = new QGraphicsView;
    view->setScene(scene);
    view->resize(400,400);
    view->show();
    return a.exec();
}

(7)運(yùn)行程序,將程序中用到的圖片保存到該工程的D:\Qt\CH7\CH701\build-Butterfly-Desktop_Qt_5_8_0_MinGW_32bit-Debug文件夾中,運(yùn)行結(jié)果如圖7.5所示。
Qt5開發(fā)及實(shí)例V2.0-第七章-Qt圖形視圖框架,QT5,ARM?MCU,Linux,qt,數(shù)據(jù)庫(kù),服務(wù)器,開發(fā)語(yǔ)言,運(yùn)維,linux

7.2.2 地圖瀏覽器

【例】(難度中等)(CH702)設(shè)計(jì)一個(gè)地圖瀏覽器,包括地圖的瀏覽、放大、縮小,以及顯示各點(diǎn)的坐標(biāo)等,如圖7.6所示。

操作步驟如下。
(1)新建Qt Widgets Application (詳見1.3.1節(jié)),項(xiàng)目名稱為“MapWidget”,基類選擇“QMainWindow”,類名命名默認(rèn)為“MainWindow”,取消“創(chuàng)建界面”復(fù)選框的選中狀態(tài)。單擊“下一步”按鈕,最后單擊“完成”按鈕,完成該項(xiàng)目工程的建立。
(2)在“MapWidget”項(xiàng)目名上單擊鼠標(biāo)右鍵,在彈出的快捷菜單中選擇“添加新文件…”菜單項(xiàng),在彈出的對(duì)話框中選擇“C++ Class”選項(xiàng)。單擊“Choose…”按鈕,彈出對(duì)話框,在“Base class”后面的文本框中輸入基類名“QGraphicsView”(手工添加),在“Class name”后面的文本框中輸入類的名稱“MapWidget”。
(3)單擊“下一步”按鈕,單擊“完成”按鈕,添加文件“mapwidget.h”和文件“mapwidget.cpp”。
(4)MapWidget類繼承自QGraphicsView類,作為地圖瀏覽器的主窗體。在頭文件“mapwidget.h”中完成的代碼。
(5)在源文件“mapwidget.cpp”中完成的代碼。
(6)新建一個(gè)文本文件“maps.txt”,利用該文本文件描述與地圖相關(guān)的信息,將該文件保存在該工程下的D:\Qt\CH7\CH702\ build-MapWidget-Desktop_Qt_5_ 4_0_ MinGW_32bit-Debug文件中,文件內(nèi)容為:
China.jpg 114.4665527 35.96022297 119.9597168 31.3911575
(7)打開“mapwidget.cpp”文件,添加讀取地圖信息readMap()函數(shù)的具體實(shí)現(xiàn)代碼如下:

void MapWidget::readMap()            			//讀取地圖信息
{
    QString mapName;
    QFile mapFile("maps.txt");			//(a)
    int ok = mapFile.open(QIODevice::ReadOnly);//以“只讀”方式打開此文件
    if(ok)								//分別讀取地圖的名稱和四個(gè)經(jīng)緯度信息
    {
        QTextStream ts(&mapFile);
        if(!ts.atEnd())
        {
            ts>>mapName;
            ts>>x1>>y1>>x2>>y2;
        }
    }
    map.load(mapName);							//將地圖讀取至私有變量map中
}

根據(jù)縮放滑動(dòng)條的當(dāng)前值,確定縮放的比例,調(diào)用scale()函數(shù)實(shí)現(xiàn)地圖縮放。完成地圖縮放功能的slotZoom()函數(shù)的具體實(shí)現(xiàn)代碼內(nèi)容如下:

void MapWidget::slotZoom(int value)   	//地圖縮放
{
    qreal s;
    if(value>zoom)                 		//放大
    {
        s=pow(1.01,(value-zoom));
    }
    else                             		//縮小
    {
        s=pow(1/1.01,(zoom-value));
    }
    scale(s,s);
    zoom = value;
}

QGraphicsView類的drawBackground()函數(shù)中以地圖圖片重繪場(chǎng)景的背景來實(shí)現(xiàn)地圖顯示。具體實(shí)現(xiàn)代碼如下:

void MapWidget::drawBackground(QPainter *painter, const QRectF &rect)
{
    painter->drawPixmap(int(sceneRect().left()),int(sceneRect(). top()), map);
}

響應(yīng)鼠標(biāo)移動(dòng)事件mouseMoveEvent()函數(shù),完成某點(diǎn)在各層坐標(biāo)中的映射及顯示。具體實(shí)現(xiàn)代碼如下:

void MapWidget::mouseMoveEvent(QMouseEvent *event)
{
    //QGraphicsView 坐標(biāo)
    QPoint viewPoint = event->pos();
    viewCoord->setText(QString::number(viewPoint.x())+","+
                       QString::number(viewPoint.y()));
    //QGraphicsScene 坐標(biāo)
    QPointF scenePoint = mapToScene(viewPoint);
    sceneCoord->setText(QString::number(scenePoint.x())+","+
                        QString::number(scenePoint.y()));
    //地圖坐標(biāo)(經(jīng)、緯度值)
    QPointF latLon = mapToMap(scenePoint);
    mapCoord->setText(QString::number(latLon.x())+","+
                      QString::number(latLon.y()));
}

完成從場(chǎng)景坐標(biāo)至地圖坐標(biāo)的轉(zhuǎn)換mapToMap()函數(shù)。具體實(shí)現(xiàn)代碼如下:

QPointF MapWidget::mapToMap(QPointF p)
{
    QPointF latLon;
    qreal w =sceneRect().width();
    qreal h =sceneRect().height();
    qreal lon = y1-((h/2+p.y())*abs(y1-y2)/h);
    qreal lat = x1+((w/2+p.x())*abs(x1-x2)/w);
    latLon.setX(lat);
    latLon.setY(lon);
    return latLon;
}

(8)下面是文件“main.cpp”的具體代碼:

#include <QApplication>
#include "mapwidget.h"
#include <QFont>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QFont font("ARPL KaitiM GB",12);
    font.setBold(true);
    a.setFont(font);
    MapWidget mapWidget;
    mapWidget.show();
    return a.exec();
}

(9)將程序用到的圖片保存到該工程的D:\Qt\CH7\CH702\build-MapWidget-Desktop_Qt_5_8_0_MinGW_32bit-Debug文件夾中,運(yùn)行結(jié)果如圖7.6所示。

7.2.3 圖元?jiǎng)?chuàng)建

【例】(難度中等)(CH703)設(shè)計(jì)窗體,顯示各種類型QGraphicsItem(包括不停閃爍的圓及來回移動(dòng)的星星等),如圖7.7所示。
Qt5開發(fā)及實(shí)例V2.0-第七章-Qt圖形視圖框架,QT5,ARM?MCU,Linux,qt,數(shù)據(jù)庫(kù),服務(wù)器,開發(fā)語(yǔ)言,運(yùn)維,linux

實(shí)現(xiàn)步驟如下。
(1)新建Qt Widgets Application(詳見1.3.1節(jié)),項(xiàng)目名稱為“GraphicsItem”,基類選擇“QMainWindow”,類名命名默認(rèn)為“MainWindow”,取消“創(chuàng)建界面”復(fù)選框的選中狀態(tài)。單擊“下一步”按鈕,最后單擊“完成”按鈕,完成該項(xiàng)目工程的建立。
(2)MainWindow類繼承自QMainWindow作為主窗體,包含一個(gè)加入圖元的各種操作的菜單欄,以及一個(gè)顯示各種類型圖元的QGraphicsView作為主窗體的centralWidget?!癿ainwindow.h”文件的具體代碼實(shí)現(xiàn)內(nèi)容。
(3)“mainwindow.cpp”文件中的代碼。
(4)將程序中所用圖片保存到該工程的D:\Qt\CH7\CH703\build-GraphicsItem-Desktop_Qt_5_8_0_MinGW_32bit-Debug文件夾下,此時(shí)運(yùn)行效果如圖7.8所示。
Qt5開發(fā)及實(shí)例V2.0-第七章-Qt圖形視圖框架,QT5,ARM?MCU,Linux,qt,數(shù)據(jù)庫(kù),服務(wù)器,開發(fā)語(yǔ)言,運(yùn)維,linux
以上完成了主窗體的顯示工作,下面介紹如何實(shí)現(xiàn)圓的閃爍功能。
(1)在“GraphicsItem”項(xiàng)目名上單擊鼠標(biāo)右鍵,在彈出的快捷菜單中選擇“添加新文件…”菜單項(xiàng),在彈出的對(duì)話框中選擇“C++ Class”選項(xiàng)。單擊“Choose…”按鈕,彈出對(duì)話框,在“Base class”后面的下拉列表框中選擇基類名“QObject”,在“Class name”后面的文本框中輸入類的名稱“FlashItem”。
(2)單擊“下一步”按鈕,單擊“完成”按鈕,添加文件“flashitem.h”和文件“flashitem.cpp”。

(3)“flashitem.h”文件的具體代碼如下:

#include <QGraphicsItem>
#include <QPainter>
class FlashItem : public QObject,public QGraphicsItem
{
    Q_OBJECT
public:
    explicit FlashItem(QObject *parent = 0);
    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    void timerEvent(QTimerEvent *);
private:
    bool flash;
    QTimer *timer;
signals:
public slots:
};

(4)“flashitem.cpp”文件的具體代碼如下:

#include "flashitem.h"
FlashItem::FlashItem(QObject *parent) :  QObject(parent)
{
    flash=true;			//為顏色切換標(biāo)識(shí)賦初值
    setFlag(ItemIsMovable);	//(a)
    startTimer(1000);		//啟動(dòng)一個(gè)定時(shí)器,以1000毫秒為時(shí)間間隔
}

定義圖元邊界的函數(shù)boundingRect(),完成以圖元坐標(biāo)系為基礎(chǔ),增加兩個(gè)像素點(diǎn)的冗余工作。具體實(shí)現(xiàn)代碼如下:

QRectF FlashItem::boundingRect() const
{
    qreal adjust = 2;
    return QRectF(-10-adjust,-10-adjust,43+adjust,43+adjust);
}

為自定義圖元重繪的函數(shù)paint()具體實(shí)現(xiàn)代碼如下:

void FlashItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->setPen(Qt::NoPen);		//閃爍圖元的陰影區(qū)不繪制邊線
    painter->setBrush(Qt::darkGray);		//閃爍圖元的陰影區(qū)的陰影畫刷顏色為深灰
    painter->drawEllipse(-7,-7,40,40);	//繪制陰影區(qū)
    painter->setPen(QPen(Qt::black,0));	
				//閃爍區(qū)的橢圓邊線顏色為黑色、線寬為0
    painter->setBrush(flash?(Qt::red):(Qt::yellow)); //(a)
    painter->drawEllipse(-10,-10,40,40);	      //(b)
}

定時(shí)器響應(yīng)函數(shù)timerEvent()完成顏色切換標(biāo)識(shí)的反置,并在每次反置后調(diào)用update()函數(shù)重繪圖元以實(shí)現(xiàn)閃爍的效果。具體實(shí)現(xiàn)代碼如下:

void FlashItem::timerEvent(QTimerEvent *)
{
    flash=!flash;
    update();
}

(5)在“mainwindow.h”文件中添加代碼如下:

public slots:    
    void slotAddFlashItem();
private:
    QAction *addFlashItemAct;

(6)在“mainwindow.cpp”文件中添加代碼如下:

#include "flashitem.h"

其中,在createActions()函數(shù)中添加代碼如下:

addFlashItemAct = new QAction(tr("加入閃爍圓"),this);
connect(addFlashItemAct,SIGNAL(triggered()),this,SLOT(slotAddFlashItem()));

在createMenus()函數(shù)中添加代碼如下:

itemsMenu->addAction(addFlashItemAct);

在initScene()函數(shù)中添加代碼如下:

for(i=0;i<3;i++)      
        slotAddFlashItem();

函數(shù)slotAddFlashItem()具體實(shí)現(xiàn)代碼如下:

void MainWindow::slotAddFlashItem()  	//在場(chǎng)景中加入一個(gè)閃爍圖元
{
    FlashItem *item = new FlashItem;
    scene->addItem(item);
    item->setPos((qrand()%int(scene->sceneRect().width()))-200,
                 (qrand()%int(scene->sceneRect().height()))-200);
}

(7)運(yùn)行效果如圖7.9所示。
Qt5開發(fā)及實(shí)例V2.0-第七章-Qt圖形視圖框架,QT5,ARM?MCU,Linux,qt,數(shù)據(jù)庫(kù),服務(wù)器,開發(fā)語(yǔ)言,運(yùn)維,linux

下面將接著完成實(shí)現(xiàn)星星移動(dòng)的功能。
(1)向項(xiàng)目中添加一個(gè)新的C++類,類名命名為“StartItem”,操作步驟同前。StartItem類繼承自QGraphicsItem類,實(shí)際上是一個(gè)圖片圖元。
“startitem.h”文件的具體代碼如下:

#include <QGraphicsItem>
#include <QPainter>
class StartItem : public QGraphicsItem
{
public:
    StartItem();
    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
private:
    QPixmap pix;
};

(2)StartItem構(gòu)造函數(shù)中僅完成讀取圖片信息的工作。
“startitem.cpp”文件中的具體代碼如下:

#include "startitem.h"
StartItem::StartItem()
{
    pix.load("star.png");
}

定義圖元的邊界函數(shù)boundingRect(),它是所有自定義圖元均必須實(shí)現(xiàn)的函數(shù),代碼如下:

QRectF StartItem::boundingRect() const
{
    return QRectF(-pix.width()/2,-pix.height()/2,pix.width(),pix. height());
}

自定義圖元重繪函數(shù)paint(),代碼如下:

void StartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget)
{
    painter->drawPixmap(boundingRect().topLeft(),pix);
}

(3)在“mainwindow.h”文件中添加代碼如下:

public slots:    
    void slotAddAnimationItem();
private:
    QAction *addAnimItemAct;

(4)在“mainwindow.cpp”文件中添加代碼如下:

#include "startitem.h"
#include <QGraphicsItemAnimation>
#include <QTimeLine>

其中,在createActions()函數(shù)中添加代碼如下:

addAnimItemAct = new QAction(tr("加入 星星"),this);
connect(addAnimItemAct,SIGNAL(triggered()),this,SLOT(slotAddAnimationItem()));

在createMenus()函數(shù)中添加代碼如下:
itemsMenu->addAction(addAnimItemAct);
在initScene()函數(shù)中添加代碼如下:

for(i=0;i<3;i++)      
    slotAddAnimationItem();

實(shí)現(xiàn)函數(shù)slotAddAnimationItem()的具體代碼如下:

void MainWindow::slotAddAnimationItem() 	//在場(chǎng)景中加入一個(gè)動(dòng)畫星星
{
    StartItem *item = new StartItem;
    QGraphicsItemAnimation *anim = new QGraphicsItemAnimation;
    anim->setItem(item);
    QTimeLine *timeLine = new QTimeLine(4000);
    timeLine->setCurveShape(QTimeLine::SineCurve);
    timeLine->setLoopCount(0);
    anim->setTimeLine(timeLine);
    int y =(qrand()%400)-200;
    for(int i=0;i<400;i++)
    {
        anim->setPosAt(i/400.0,QPointF(i-200,y));
    }
    timeLine->start();
    scene->addItem(item);
}

(5)最終運(yùn)行結(jié)果如圖7.7所示,圖中的小星星會(huì)不停地左右移動(dòng)。

7.2.4 圖元的旋轉(zhuǎn)、縮放、切變和位移

【例】(難度中等)(CH704)設(shè)計(jì)界面,實(shí)現(xiàn)蝴蝶各種變形。如圖7.10所示。
Qt5開發(fā)及實(shí)例V2.0-第七章-Qt圖形視圖框架,QT5,ARM?MCU,Linux,qt,數(shù)據(jù)庫(kù),服務(wù)器,開發(fā)語(yǔ)言,運(yùn)維,linux
(1)新建Qt Widgets Application(詳見1.3.1節(jié)),項(xiàng)目名稱為“ItemWidget”,基類選擇“QWidget”,類名命名為“MainWidget”,取消“創(chuàng)建界面”復(fù)選框的選中狀態(tài)。單擊“下一步”按鈕,最后單擊“完成”按鈕,完成該項(xiàng)目工程的建立。
(2)MainWidget類繼承自QWidget,作為主窗體類,用于對(duì)圖元的顯示,包含一個(gè)控制面板區(qū)及一個(gè)顯示區(qū)。

“mainwidget.h”文件中的代碼如下:

#include <QWidget>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QFrame>
class MainWidget : public QWidget
{
    Q_OBJECT
public:
    MainWidget(QWidget *parent = 0);
    ~MainWidget();
    void createControlFrame();
private:
    int angle;
    qreal scaleValue;
    qreal shearValue;
    qreal translateValue;
    QGraphicsView *view;
    QFrame *ctrlFrame;
};

(3)“mainwidget.cpp”文件中的具體代碼。
右側(cè)的控制面板區(qū)分為旋轉(zhuǎn)控制區(qū)、縮放控制區(qū)、切變控制區(qū)及位移控制區(qū),每個(gè)區(qū)均由包含一個(gè)QSlider對(duì)象的QGroupBox對(duì)象實(shí)現(xiàn),具體實(shí)現(xiàn)代碼。
(4)運(yùn)行效果如圖7.11所示。
Qt5開發(fā)及實(shí)例V2.0-第七章-Qt圖形視圖框架,QT5,ARM?MCU,Linux,qt,數(shù)據(jù)庫(kù),服務(wù)器,開發(fā)語(yǔ)言,運(yùn)維,linux
上面完成的是主窗體的功能,下面介紹用于變形顯示的圖元的制作。
(1)在“ItemWidget”項(xiàng)目名上單擊鼠標(biāo)右鍵,在彈出的快捷菜單中選擇“添加新文件…”菜單項(xiàng),在彈出的對(duì)話框中選擇“C++ Class”選項(xiàng)。單擊“Choose…”按鈕,彈出對(duì)話框,在“Base class”后面的文本框中輸入基類名“QGraphicsItem”(手工添加),在“Class name”后面的文本框中輸入類的名稱“PixItem”。
(2)單擊“下一步”按鈕,單擊“完成”按鈕,添加文件“pixitem.h”和文件“pixitem.cpp”。
(3)自定義PixItem類繼承自QGraphicsItem類。

“pixitem.h”文件中的具體代碼如下:

#include <QGraphicsItem>
#include <QPixmap>
#include <QPainter>
class PixItem : public QGraphicsItem
{
public:
    PixItem(QPixmap *pixmap);
    QRectF boundingRect() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
private:
    QPixmap pix;     		//作為圖元顯示的圖片
};

(4)PixItem的構(gòu)造函數(shù)只是初始化了變量pix。“pixitem.cpp”文件中的具體內(nèi)容如下:
#include “pixitem.h”

PixItem::PixItem(QPixmap *pixmap)
{
    pix = *pixmap;
}

定義圖元邊界的函數(shù)boundingRect(),完成以圖元坐標(biāo)系為基礎(chǔ)增加兩個(gè)像素點(diǎn)的冗余的工作。具體實(shí)現(xiàn)代碼如下:

QRectF PixItem::boundingRect() const
{
    return QRectF(-2-pix.width()/2,-2-pix.height()/2,pix.width()+4, pix. height()+4);
}

重畫函數(shù)只需QPainter的drawPixmap()函數(shù)將圖元圖片繪出即可。具體代碼如下:

void PixItem::paint(QPainter *painter, const QStyleOptionGraphicsItem  *option,QWidget *widget)
{
    painter->drawPixmap(-pix.width()/2,-pix.height()/2,pix);
}

(5)在“mainwidget.h”文件中添加代碼如下:

#include "pixitem.h"
private:
PixItem *pixItem;

(6)打開“mainwidget.cpp”文件,在語(yǔ)句scene->setSceneRect(-200,-200,400,400)與view = new QGraphicsView之間添加如下代碼:

QPixmap *pixmap = new  QPixmap("image.png");
pixItem = new PixItem(pixmap);
scene->addItem(pixItem);
pixItem->setPos(0,0);

(7)運(yùn)行效果如圖7.12所示。
Qt5開發(fā)及實(shí)例V2.0-第七章-Qt圖形視圖框架,QT5,ARM?MCU,Linux,qt,數(shù)據(jù)庫(kù),服務(wù)器,開發(fā)語(yǔ)言,運(yùn)維,linux
上述內(nèi)容只是完成了圖元圖片的加載顯示。下面介紹實(shí)現(xiàn)圖元的各種變形的實(shí)際功能。
(1)在“mainwidget.h”文件中添加槽函數(shù)聲明如下:

public slots:
    void slotRotate(int);
    void slotScale(int);
    void slotShear(int);
    void slotTranslate(int);

(2)在“mainwidget.cpp”文件中添加頭文件:

#include <math.h>

其中,在createControlFrame()函數(shù)中的QVBoxLayout *frameLayout=new QVBoxLayout語(yǔ)句之前添加以下代碼:

connect(rotateSlider,SIGNAL(valueChanged(int)),this,SLOT(slotRotate(int)));
connect(scaleSlider,SIGNAL(valueChanged(int)),this,SLOT(slotScale(int)));
connect(shearSlider,SIGNAL(valueChanged(int)),this,SLOT(slotShear(int)));
connect(translateSlider,SIGNAL(valueChanged(int)),this,SLOT(slotTranslate(int)));

實(shí)現(xiàn)圖元的旋轉(zhuǎn)功能函數(shù)slotRotate(),主要是調(diào)用QGraphicsView類的rotate()函數(shù)實(shí)現(xiàn)的,它的參數(shù)為旋轉(zhuǎn)角度的度數(shù)值,具體實(shí)現(xiàn)代碼如下:

void MainWidget::slotRotate(int value)
{
    view->rotate(value-angle);
    angle = value;
}

實(shí)現(xiàn)圖元的縮放功能函數(shù)slotScale(),主要是調(diào)用QGraphicsView類的scale()函數(shù)實(shí)現(xiàn)的,它的參數(shù)為縮放的比例,具體實(shí)現(xiàn)代碼如下:

void MainWidget::slotScale(int value)
{
    qreal s;
    if(value>scaleValue)
        s=pow(1.1,(value-scaleValue));
    else
        s=pow(1/1.1,(scaleValue-value));
    view->scale(s,s);
    scaleValue=value;
}

實(shí)現(xiàn)圖元的切變功能函數(shù)slotShear(),主要是調(diào)用QGraphicsView類的shear()函數(shù)實(shí)現(xiàn)的,它的參數(shù)為切變的比例,具體實(shí)現(xiàn)代碼如下:

void MainWidget::slotShear(int value)
{
    view->shear((value-shearValue)/10.0,0);
    shearValue=value;
}

實(shí)現(xiàn)圖元的位移功能函數(shù)slotTranslate(),主要是調(diào)用QGraphicsView類的translate()函數(shù)實(shí)現(xiàn)的,它的參數(shù)為位移的大小,具體實(shí)現(xiàn)代碼如下:

void MainWidget::slotTranslate(int value)
{
    view->translate(value-translateValue,value-translateValue);
    translateValue=value;
}

(3)最終運(yùn)行結(jié)果如圖7.10所示,讀者可以試著拖曳滑塊觀看圖形的各種變換效果。



本章相關(guān)例程源碼下載

1.Qt5開發(fā)及實(shí)例_CH701.rar 下載

Qt5開發(fā)及實(shí)例_CH701.rar

2.Qt5開發(fā)及實(shí)例_CH702.rar 下載

Qt5開發(fā)及實(shí)例_CH702.rar

3.Qt5開發(fā)及實(shí)例_CH703.rar 下載

Qt5開發(fā)及實(shí)例_CH703.rar

4.Qt5開發(fā)及實(shí)例_CH704.rar 下載

Qt5開發(fā)及實(shí)例_CH704.rar文章來源地址http://www.zghlxwxcb.cn/news/detail-730993.html

到了這里,關(guān)于Qt5開發(fā)及實(shí)例V2.0-第七章-Qt圖形視圖框架的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 第七章:敏捷開發(fā)工具方法-part1-敏捷開發(fā)基礎(chǔ)

    第七章:敏捷開發(fā)工具方法-part1-敏捷開發(fā)基礎(chǔ)

    敏捷開發(fā)背景 速度是企業(yè)競(jìng)爭(zhēng)致勝的關(guān)鍵因素,軟件項(xiàng)目的最大挑戰(zhàn)在于一方面需要應(yīng)付變動(dòng)中的需求,一方面需要在有限的時(shí)間完成項(xiàng)目,傳統(tǒng)的軟件工程難以滿足這些要求 所以軟件團(tuán)隊(duì)除了在技術(shù)上必須日益精進(jìn),更需要運(yùn)用有效的開發(fā)流程,以確保團(tuán)隊(duì)能夠發(fā)揮綜效

    2024年02月09日
    瀏覽(44)
  • 【鴻蒙開發(fā)】第七章 ArkTS語(yǔ)言UI范式-基礎(chǔ)語(yǔ)法

    【鴻蒙開發(fā)】第七章 ArkTS語(yǔ)言UI范式-基礎(chǔ)語(yǔ)法

    通過前面的章節(jié),我們基本清楚鴻蒙應(yīng)用開發(fā)用到的語(yǔ)言和項(xiàng)目基本結(jié)構(gòu),在【鴻蒙開發(fā)】第四章 Stage應(yīng)用模型及項(xiàng)目結(jié)構(gòu)也提到過ArkTS的UI范式的 基本語(yǔ)法 、 狀態(tài)管理 、 渲染控制 等能力,簡(jiǎn)要介紹如下: 基本語(yǔ)法 : ArkTS 定義了 聲明式UI描述 、 自定義組件 和 動(dòng)態(tài)擴(kuò)展

    2024年02月03日
    瀏覽(24)
  • 第七章:敏捷開發(fā)工具方法-part2-CI/CD工具介紹

    第七章:敏捷開發(fā)工具方法-part2-CI/CD工具介紹

    什么是CI/Cd? CI-Continuous integration : 持續(xù)集成 是指多名開發(fā)者在開發(fā)不同功能代碼的過程當(dāng)中,可以頻繁的將代嗎行合并到一起并切相互不影響工作。 CD-continuous deployment : 持續(xù)部署 是基于某種工具或平臺(tái)實(shí)現(xiàn)代碼自動(dòng)化的構(gòu)建、測(cè)試和部署到線上環(huán)境以實(shí)現(xiàn)交付高質(zhì)量的

    2024年02月09日
    瀏覽(29)
  • 第七章 圖論

    第七章 圖論

    第七章 圖論 一、數(shù)據(jù)結(jié)構(gòu)定義 圖的鄰接矩陣存儲(chǔ)法 圖的鄰接表存儲(chǔ)法 把所有節(jié)點(diǎn)存儲(chǔ)為節(jié)點(diǎn)數(shù)組,每個(gè)節(jié)點(diǎn)里有自己的數(shù)據(jù)和一個(gè)邊指針,這個(gè)邊指針相當(dāng)于一個(gè)鏈表的頭指針,這個(gè)鏈表里存放所有與這個(gè)節(jié)點(diǎn)相連的邊,邊里存放該邊指向的節(jié)點(diǎn)編號(hào)和下一條邊指針 圖的

    2024年02月14日
    瀏覽(79)
  • 第七章 函數(shù)矩陣

    第七章 函數(shù)矩陣

    和矩陣函數(shù)不同的是,函數(shù)矩陣本質(zhì)上是一個(gè)矩陣,是以函數(shù)作為元素的矩陣。 矩陣函數(shù)本質(zhì)上是一個(gè)矩陣,是以矩陣作為自變量的函數(shù)。 函數(shù)矩陣和數(shù)字矩陣的運(yùn)算法則完全相同。 不過矩陣的元素 a i j ( x ) a_{ij}(x) a ij ? ( x ) 需要是閉區(qū)間 [ a , b ] [a,b] [ a , b ] 上的實(shí)函數(shù)

    2024年02月04日
    瀏覽(22)
  • 第七章金融中介

    ?? ? ? ? 金融中介是通過向資金盈余者發(fā)行 間接融資合約( 如存款單),并和資金短缺者達(dá)成 間接投資合約 (發(fā)放信貸)或購(gòu)買其發(fā)行的證券,在資金供求方之間融通資金,對(duì)資金跨期、跨域進(jìn)行優(yōu)化配置的金融機(jī)構(gòu)。 ? ? ? ? 金融體系由金融市場(chǎng)和金融中介構(gòu)成,以銀行業(yè)為

    2024年02月04日
    瀏覽(27)
  • python第七章(字典)

    python第七章(字典)

    一。字典(類型為dict)的特點(diǎn): 1.符號(hào)為大括號(hào) 2.數(shù)據(jù)為鍵值對(duì)形式出現(xiàn) 3.各個(gè)鍵值對(duì)之間以逗號(hào)隔開 格式:str1={\\\'name\\\':\\\'Tom\\\'}? name相當(dāng)于鍵值(key),Tom相當(dāng)于值 二??兆值涞膭?chuàng)建方法 三。字典的基本操作(增刪改查) 1.字典的增加操作:字典序列[key] = 值 注意點(diǎn):如果存

    2024年01月24日
    瀏覽(46)
  • 第七章 測(cè)試

    第七章 測(cè)試

    7.1.1 選擇程序設(shè)計(jì)語(yǔ)言 1. 計(jì)算機(jī)程序設(shè)計(jì)語(yǔ)言基本上可以分為匯編語(yǔ)言和高級(jí)語(yǔ)言 2. 從應(yīng)用特點(diǎn)看,高級(jí)語(yǔ)言可分為基礎(chǔ)語(yǔ)言、結(jié)構(gòu)化語(yǔ)言、專用語(yǔ)言 01 有理想的模塊化機(jī)制; 02 可讀性好的控制結(jié)構(gòu)和數(shù)據(jù)結(jié)構(gòu); 03 便于調(diào)試和提高軟件可靠性; 04 編譯程序發(fā)現(xiàn)程序錯(cuò)誤的

    2024年02月08日
    瀏覽(29)
  • [JavaScript] 第七章 對(duì)象

    [JavaScript] 第七章 對(duì)象

    ??作者主頁(yè):青花鎖 ??簡(jiǎn)介:Java領(lǐng)域優(yōu)質(zhì)創(chuàng)作者??、Java微服務(wù)架構(gòu)公號(hào)作者?? ??簡(jiǎn)歷模板、學(xué)習(xí)資料、面試題庫(kù)、技術(shù)互助 ??文末獲取聯(lián)系方式 ?? [Java項(xiàng)目實(shí)戰(zhàn)] 介紹Java組件安裝、使用;手寫框架等 [Aws服務(wù)器實(shí)戰(zhàn)] Aws Linux服務(wù)器上操作nginx、git、JDK、Vue等 [Java微服務(wù)

    2024年02月02日
    瀏覽(61)
  • 數(shù)據(jù)結(jié)構(gòu)第七章

    數(shù)據(jù)結(jié)構(gòu)第七章

    圖(Graph)G由兩個(gè)集合V和E組成,記為G=(V, E),其中V是頂點(diǎn)的有窮非空集合,E是V中頂點(diǎn)偶對(duì)的有窮集合,這些頂點(diǎn)偶對(duì)稱為邊。V(G)和E(G)通常分別表示圖G的頂點(diǎn)集合和邊集合,E(G)可以為空集。若EG)為空,則圖G只有頂點(diǎn)而沒有邊。 子圖:假設(shè)有兩個(gè)圖G=(V,E)和G1=(V1,E1);如果V1

    2024年02月03日
    瀏覽(27)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包