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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

[Qt教程] 第19篇 2D绘图(九)图形视图框架(上)

發(fā)布時(shí)間:2024/4/20 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [Qt教程] 第19篇 2D绘图(九)图形视图框架(上) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

[Qt教程]?第19篇 2D繪圖(九)圖形視圖框架(上)

樓主 ?發(fā)表于 2013-5-4 15:26:20?|?查看: 1798|?回復(fù): 26
圖形視圖框架(上)
版權(quán)聲明




導(dǎo)語(yǔ)
在前面講的基本繪圖中,我們可以自己繪制各種圖形,并且控制它們。但是,如果需要同時(shí)繪制很多個(gè)相同或不同的圖形,并且要控制它們的移動(dòng),檢測(cè)它們的碰撞和疊加;或者我們想讓自己繪制的圖形可以拖動(dòng)位置,進(jìn)行縮放和旋轉(zhuǎn)等操作。實(shí)現(xiàn)這些功能,要是還使用以前的方法,那么會(huì)十分困難。解決這些問(wèn)題,可以使用Qt提供的圖形視圖框架。 ? ?? ??圖形視圖可以對(duì)大量定制的2D圖形項(xiàng)進(jìn)行管理和相互作用。視圖部件可以讓所有圖形項(xiàng)可視化,它還提供了縮放和旋轉(zhuǎn)功能。我們?cè)趲椭兴阉?/span>Graphics View?關(guān)鍵字,內(nèi)容如下圖:

這里一開(kāi)始對(duì)這個(gè)框架進(jìn)行了簡(jiǎn)單介紹,整個(gè)圖形視圖結(jié)構(gòu)主要包含三部分:場(chǎng)景(Scene)、視圖(View)和圖形項(xiàng)(Item),它們分別對(duì)應(yīng)?QGraphicsScene?QGraphicsView?QGraphicsItem三個(gè)類。其實(shí)圖形視圖框架是一組類的集合,在幫助中可以看到所有與它相關(guān)的類。下面我們就開(kāi)始結(jié)合程序?qū)φ麄€(gè)框架進(jìn)行介紹。



環(huán)境:Windows Xp + Qt 4.8.4+QtCreator 2.6.2



目錄
一、基本應(yīng)用 二、圖形項(xiàng)(QGraphicsItem (一)自定義圖形項(xiàng) (二)光標(biāo)和提示 (三)拖放 (四)鍵盤與鼠標(biāo)事件 (五)碰撞檢測(cè) (六)移動(dòng) (七)動(dòng)畫 (八)右鍵菜單



正文

一、基本應(yīng)用 我們新建空的Qt項(xiàng)目(在其他項(xiàng)目中),項(xiàng)目名稱為graphicsView01。然后在這個(gè)項(xiàng)目中添加新的C++?源文件,命名為main.cpp 我們將main.cpp的內(nèi)容更改如下。 #include <QtGui>
int main(int argc,char* argv[ ]) { QApplication app(argc,argv);
QGraphicsScene *scene = new QGraphicsScene;??//場(chǎng)景 QGraphicsRectItem *item = new QGraphicsRectItem(100,100,50,50);??//矩形項(xiàng) scene->addItem(item);??//項(xiàng)添加到場(chǎng)景 QGraphicsView *view = new QGraphicsView; //視圖 view->setScene(scene);??//視圖關(guān)聯(lián)場(chǎng)景 view->show();??//顯示視圖
return app.exec(); } 這里我們建立了一個(gè)最簡(jiǎn)單的基于這個(gè)圖形視圖框架的程序。分別新建了一個(gè)場(chǎng)景,一個(gè)圖形項(xiàng)和一個(gè)視圖,并將圖形項(xiàng)添加到場(chǎng)景中,將視圖與場(chǎng)景關(guān)聯(lián),最后顯示視圖就可以了。基于這個(gè)框架的所有程序都是這樣實(shí)現(xiàn)的。運(yùn)行效果如下。

就像我們看到的,場(chǎng)景是管理圖形項(xiàng)的,所有的圖形項(xiàng)必須添加到一個(gè)場(chǎng)景中,但是場(chǎng)景本身無(wú)法可視化,我們要想看到場(chǎng)景上的內(nèi)容,必須使用視圖。下面我們分別對(duì)圖形項(xiàng)、場(chǎng)景和視圖進(jìn)行介紹。


二、圖形項(xiàng)(QGraphicsItem QGraphicsItem類是所有圖形項(xiàng)的基類。圖形視圖框架對(duì)一些典型的形狀提供了一些標(biāo)準(zhǔn)的圖形項(xiàng)。比如上面我們使用的矩形(QGraphicsRectItem)、橢圓(QGraphicsEllipseItem)、文本(QGraphicsTextItem)等多個(gè)圖形項(xiàng)。但只有繼承QGraphicsItem 類實(shí)現(xiàn)我們自定義的圖形項(xiàng)時(shí),才能顯示出這個(gè)類的強(qiáng)大。QGraphicsItem支持以下功能:
  • 鼠標(biāo)的按下、移動(dòng)、釋放和雙擊事件,也支持鼠標(biāo)懸停、滾輪和右鍵菜單事件。
  • 鍵盤輸入焦點(diǎn)和鍵盤事件
  • 拖放
  • 利用QGraphicsItemGroup進(jìn)行分組
  • 碰撞檢測(cè)


(一)自定義圖形項(xiàng) 1.在前面的項(xiàng)目中添加新的C++類,類名設(shè)為 MyItem,基類設(shè)為QGraphicsItem。

2.然后,我們?cè)趍yitem.h文件中添加頭文件#include <QtGui>。(說(shuō)明:QtGui模塊里面包含了所有圖形界面類,所以為了簡(jiǎn)便,這里只包含了該頭文件,正式開(kāi)發(fā)程序時(shí)不推薦這么做!)

3.再添加兩個(gè)函數(shù)的聲明:
QRectFboundingRect() const; voidpaint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget*widget);

4.下面到myitem.cpp中對(duì)兩個(gè)函數(shù)進(jìn)行定義:
QRectFMyItem::boundingRect() const { qreal penWidth = 1; return QRectF(0 - penWidth / 2, 0 -penWidth / 2, 20 + penWidth, 20 + penWidth); }

voidMyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget) { Q_UNUSED(option);??//標(biāo)明該參數(shù)沒(méi)有使用 Q_UNUSED(widget); painter->setBrush(Qt::red); painter->drawRect(0,0,20,20); }


5.下面到main.cpp中添加#include "myitem.h" 然后將以前那個(gè)矩形項(xiàng)的定義語(yǔ)句改為:
MyItem *item =new MyItem;
運(yùn)行程序,效果如下:
可以看到,我們要繼承QGraphicsItem類實(shí)現(xiàn)自定義的圖形項(xiàng),必須先實(shí)現(xiàn)兩個(gè)純虛函數(shù)boundingRect()paint(),前者用于定義Item的繪制范圍,后者用于繪制圖形項(xiàng)。其實(shí)boundingRect()還有很多用途,后面會(huì)涉及到。


(二)光標(biāo)和提示
1.myitem.cpp?中的構(gòu)造函數(shù)中添加兩行代碼,如下:
MyItem::MyItem() { setToolTip("Click and drag me!");??//提示 setCursor(Qt::OpenHandCursor);? ?//改變光標(biāo)形狀 }
然后運(yùn)行程序,效果如下:
當(dāng)光標(biāo)放到小方塊上時(shí),光標(biāo)變?yōu)榱耸中?#xff0c;并且彈出了提示。更多的光標(biāo)形狀可以查看 Qt::CursorShape,我們也可以使用圖片自定義光標(biāo)形狀。


(三)拖放 下面寫這樣一個(gè)程序,有幾個(gè)不同顏色的圓形和一個(gè)大矩形,我們可以拖動(dòng)圓形到矩形上,從而改變矩形的顏色為該圓形的顏色。 1.? ?? ?將上面的程序進(jìn)行改進(jìn),用來(lái)實(shí)現(xiàn)圓形圖形項(xiàng)。
myitem.h中添加一個(gè)私有變量和幾個(gè)鍵盤事件處理函數(shù)的聲明:
protected: void mousePressEvent(QGraphicsSceneMouseEvent *event); void mouseMoveEvent(QGraphicsSceneMouseEvent *event); void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); private: QColor color;
2.然后到myitem.cpp中,在構(gòu)造函數(shù)中初始化顏色變量:
color = QColor(qrand() % 256, qrand() %256, qrand() % 256); //初始化隨機(jī)顏色
paint()函數(shù)中將繪制矩形的代碼更改如下:
painter->setBrush(color); painter->drawEllipse(0, 0, 20, 20);

3.下面我們定義幾個(gè)鍵盤事件處理函數(shù):
voidMyItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { if(event->button() != Qt::LeftButton) { event->ignore();??//如果不是鼠標(biāo)左鍵按下,則忽略該事件 return; } setCursor(Qt::ClosedHandCursor); //如果是鼠標(biāo)左鍵按下,改變光標(biāo)形狀 }

voidMyItem::mouseMoveEvent(QGraphicsSceneMouseEvent *event) { if(QLineF(event->screenPos(),event->buttonDownScreenPos(Qt::LeftButton)) .length() < QApplication::startDragDistance()) { //如果鼠標(biāo)按下的點(diǎn)到現(xiàn)在的點(diǎn)的距離小于程序默認(rèn)的拖動(dòng)距離,表明沒(méi)有拖動(dòng),則返回 return; } QDrag *drag = new QDrag(event->widget()); //event所在窗口部件新建拖動(dòng)對(duì)象 QMimeData *mime = new QMimeData; //新建QMimeData對(duì)象,它用來(lái)存儲(chǔ)拖動(dòng)的數(shù)據(jù) drag->setMimeData(mime); //關(guān)聯(lián) mime->setColorData(color);??//放入顏色數(shù)據(jù)
QPixmap pix(21,21);??//新建QPixmap對(duì)象,它用來(lái)重新繪制圓形,在拖動(dòng)時(shí)顯示 pix.fill(Qt::white); QPainter painter(&pix); paint(&painter,0,0); drag->setPixmap(pix);
drag->setHotSpot(QPoint(10, 15)); //我們讓指針指向圓形的(10,15)點(diǎn) drag->exec();??//開(kāi)始拖動(dòng) setCursor(Qt::OpenHandCursor);? ?//改變光標(biāo)形狀 }

voidMyItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { setCursor(Qt::OpenHandCursor);? ?//改變光標(biāo)形狀 }

此時(shí)運(yùn)行程序,效果如下:


4.下面我們新添一個(gè)類,它用來(lái)提供矩形圖形項(xiàng),并且可以接收拖動(dòng)的數(shù)據(jù)。 myitem.h中,我們加入該類的聲明:
class RectItem : public QGraphicsItem { public: RectItem(); QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget); protected: void dragEnterEvent(QGraphicsSceneDragDropEvent *event); //拖動(dòng)進(jìn)入事件 void dragLeaveEvent(QGraphicsSceneDragDropEvent *event); //拖動(dòng)離開(kāi)事件 void dropEvent(QGraphicsSceneDragDropEvent *event);??//放入事件 private: QColor color; bool dragOver;??//標(biāo)志是否有拖動(dòng)進(jìn)入 };

5.然后進(jìn)入myitem.cpp進(jìn)行相關(guān)函數(shù)的定義:
RectItem::RectItem() { setAcceptDrops(true);??//設(shè)置接收拖放 color = QColor(Qt::lightGray); }
QRectF RectItem::boundingRect() const { return QRectF(0, 0, 50, 50); }
void RectItem::paint(QPainter *painter,const QStyleOptionGraphicsItem *option, QWidget *widget) { painter->setBrush(dragOver? color.light(130) : color);??//如果其上有拖動(dòng),顏色變亮 painter->drawRect(0,0,50,50); }

voidRectItem::dragEnterEvent(QGraphicsSceneDragDropEvent *event) { if(event->mimeData()->hasColor()) //如果拖動(dòng)的數(shù)據(jù)中有顏色數(shù)據(jù),便接收 { event->setAccepted(true); dragOver = true; update(); } else event->setAccepted(false); }
voidRectItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *event) { Q_UNUSED(event); dragOver = false; update(); }
void RectItem::dropEvent(QGraphicsSceneDragDropEvent*event) { dragOver = false; if(event->mimeData()->hasColor()) //我們通過(guò)類型轉(zhuǎn)換來(lái)獲得顏色 color =qVariantValue<QColor>(event->mimeData()->colorData()); update(); }

6.下面進(jìn)入main.cpp文件,更改main()函數(shù)中的內(nèi)容如下: int main(int argc,char* argv[ ]) { QApplication app(argc,argv);
qsrand(QTime(0,0,0).secsTo(QTime::currentTime())); //設(shè)置隨機(jī)數(shù)初值 QGraphicsScene *scene = new QGraphicsScene; for(int i=0; i<5; i++) //在不同位置新建5個(gè)圓形 { MyItem *item = new MyItem; item->setPos(i*50+20,100); scene->addItem(item); } RectItem *rect = new RectItem; //新建矩形 rect->setPos(100,200); scene->addItem(rect); QGraphicsView *view = new QGraphicsView; view->setScene(scene); view->resize(400,300); //設(shè)置視圖大小 view->show();
return app.exec(); }
這是運(yùn)行程序,效果如下:

這時(shí)我們已經(jīng)實(shí)現(xiàn)了想要的效果。可以看到,要想實(shí)現(xiàn)拖放,必須源圖形項(xiàng)和目標(biāo)圖形項(xiàng)都進(jìn)行相關(guān)設(shè)置。在源圖形項(xiàng)的鼠標(biāo)事件中新建并執(zhí)行拖動(dòng),而在目標(biāo)圖形項(xiàng)中必須指定setAcceptDrops(true); 這個(gè)函數(shù),這樣才能接收拖放,然后需要實(shí)現(xiàn)拖放的幾個(gè)事件處理函數(shù)。


(四)鍵盤與鼠標(biāo)事件
1.新建項(xiàng)目graphicsView02,然后按照(一)中自定義圖形項(xiàng)進(jìn)行操作(可以直接把那里的代碼拷貝過(guò)來(lái))。下面我們先來(lái)看鍵盤事件。
2.myitem.h文件中聲明鍵盤按下事件處理函數(shù):
protected: voidkeyPressEvent(QKeyEvent *event);
然后在myitem.cpp中進(jìn)行定義:
void MyItem::keyPressEvent(QKeyEvent*event) { moveBy(0, 10);??//相對(duì)現(xiàn)在的位置移動(dòng) }
這時(shí)運(yùn)行程序,發(fā)現(xiàn)無(wú)論怎樣方塊都不會(huì)移動(dòng)。其實(shí)要想使圖形項(xiàng)接收鍵盤事件,就必須使其可獲得焦點(diǎn)。我們?cè)跇?gòu)造函數(shù)里添加一行代碼:
setFlag(QGraphicsItem::ItemIsFocusable);??//圖形項(xiàng)可獲得焦點(diǎn)
(我們?cè)谛陆▓D形項(xiàng)時(shí)指定也是可以的,如item->setFlag(QGraphicsItem::ItemIsFocusable);
這時(shí)運(yùn)行程序,然后用鼠標(biāo)點(diǎn)擊一下方塊,再按下任意按鍵,方塊就會(huì)向下移動(dòng)。效果如下圖所示。

3.再看鼠標(biāo)事件。我們先在myitem.h文件中聲明鼠標(biāo)按下事件處理函數(shù):
voidmousePressEvent(QGraphicsSceneMouseEvent *event);
然后再myitem.cpp文件中對(duì)其進(jìn)行定義:
voidMyItem::mousePressEvent(QGraphicsSceneMouseEvent *event) { moveBy(10,0); }
此時(shí)運(yùn)行程序,點(diǎn)擊小方塊,它便會(huì)向右移動(dòng)。如果我們想讓鼠標(biāo)可以拖動(dòng)小方塊,那么我們可以重新實(shí)現(xiàn)mouseMoveEvent()函數(shù),還有一種更簡(jiǎn)單的方法是,我們?cè)跇?gòu)造函數(shù)中指明該圖形項(xiàng)是可移動(dòng)的:
setFlag(QGraphicsItem::ItemIsMovable);
(當(dāng)然我們也可以在新建圖形項(xiàng)時(shí)指定它) 運(yùn)行程序,效果如下:


(五)碰撞檢測(cè) 下面先看一個(gè)例子,再進(jìn)行講解。 我們將上面程序中myitem.cpp文件中的paint()函數(shù)中的設(shè)置畫刷的代碼更改如下:

//如果與其他圖形項(xiàng)碰撞則顯示紅色,否則顯示綠色 painter->setBrush(!collidingItems().isEmpty()?Qt::red : Qt::green);

然后再main.cpp文件中在場(chǎng)景中添加一個(gè)直線圖形項(xiàng):

QGraphicsLineItem *line = newQGraphicsLineItem(0,50,300,50); scene->addItem(line);

這時(shí)運(yùn)行程序,效果如下: ???
剛開(kāi)始,方塊是綠色的,當(dāng)我們拖動(dòng)它與直線相交時(shí),它就變成了紅色。 在QGraphicsItem類中有三個(gè)碰撞檢測(cè)函數(shù),分別是collidesWithItem()、collidesWithPath()和collidingItems(),我們使用的是第三個(gè)。第一個(gè)是該圖形項(xiàng)是否與指定的圖形項(xiàng)碰撞,第二個(gè)是該圖形項(xiàng)是否與指定的路徑碰撞,第三個(gè)是返回所有與該圖形項(xiàng)碰撞的圖形項(xiàng)的列表。在幫助中我們可以查看它們的函數(shù)原型和介紹,這里想說(shuō)明的是,這三個(gè)函數(shù)都有一個(gè)共同的參數(shù)Qt::ItemSelectionMode,它指明了怎樣去檢測(cè)碰撞。我們?cè)趲椭羞M(jìn)行查看,可以發(fā)現(xiàn)它是一個(gè)枚舉變量,一共有四個(gè)值,分別是:
  • Qt::ContainsItemShape:只有圖形項(xiàng)的shape被完全包含時(shí);
  • Qt::IntersectsItemShape:當(dāng)圖形項(xiàng)的shape被完全包含時(shí),或者圖形項(xiàng)與其邊界相交;
  • Qt::ContainsItemBoundingRect: 只有圖形項(xiàng)的bounding rectangle被完全包含時(shí);
  • Qt::IntersectsItemBoundingRect:圖形項(xiàng)的boundingrectangle被完全包含時(shí),或者圖形項(xiàng)與其邊界相交。
如果我們不設(shè)置該參數(shù),那么他默認(rèn)使用Qt::IntersectsItemShape 。這里所說(shuō)的shape是指什么呢?在QGraphicsItem類中我們可以找到shape()函數(shù),它返回的是一個(gè)QPainterPath對(duì)象,也就是說(shuō)它能確定我們圖形項(xiàng)的形狀。但是默認(rèn)的,它只是返回boundingRect()函數(shù)返回的矩形的形狀。下面我們具體驗(yàn)證一下。 在main.cpp函數(shù)中添加兩行代碼:
qDebug()<< item->shape();? ?//輸出item的shape信息 qDebug()<< item->boundingRect();??//輸出item的boundingRect信息
這時(shí)運(yùn)行程序,在下面的程序輸出窗口會(huì)輸出如下信息:
我們發(fā)現(xiàn),現(xiàn)在shapeboundingRect的大小是一樣的。這時(shí)我們?cè)诘?/span>myitem.cpp中更改函數(shù)boundingRect()函數(shù)中的內(nèi)容,將大小由20,改為50
return QRectF(0 - penWidth / 2, 0 -penWidth / 2, 50 + penWidth, 50 + penWidth);
這時(shí)再次運(yùn)行程序,效果如下:
小方塊一出來(lái)便成為了紅色,下面的輸出信息也顯示了,現(xiàn)在shape的大小也變成了50。怎樣才能使小方塊按照它本身的形狀,而不是其boundingRect的大小來(lái)進(jìn)行碰撞檢測(cè)呢?我們需要重新實(shí)現(xiàn)shape()函數(shù)。
myitem.h中,我們?cè)?/span>public里進(jìn)行函數(shù)聲明:QPainterPath shape() const;
然后到myitem.cpp中進(jìn)行其定義:
QPainterPath MyItem::shape() const { QPainterPath path; path.addRect(0,0,20,20);??//圖形項(xiàng)的真實(shí)大小 return path; }
這時(shí)我們?cè)龠\(yùn)行程序,效果如下: 可以看到,現(xiàn)在shapeboundingRect的大小已經(jīng)不同了。所以對(duì)于不是矩形的形狀,我們都可以利用shape()函數(shù)來(lái)返回它的真實(shí)形狀。

(六)移動(dòng) 對(duì)于圖形項(xiàng)的移動(dòng),我們有很多辦法實(shí)現(xiàn),也可以在很多層面上對(duì)其進(jìn)行控制,比如說(shuō)在View上控制或者在Scene上控制。但是對(duì)于大量的不同類型的圖形項(xiàng),怎樣能一起控制呢?在圖形視圖框架中提供了advance()槽函數(shù),這個(gè)函數(shù)在QGraphicsSceneQGraphicsItem中都有,在圖形項(xiàng)類中它的原型是advance(int phase)。它的實(shí)現(xiàn)流程是,我們利用QGraphicsScene類的對(duì)象調(diào)用QGraphicsSceneadvance()函數(shù),這時(shí)就會(huì)執(zhí)行兩次該場(chǎng)景中所有圖形項(xiàng)的advance(int phase)函數(shù),第一次phase0,告訴所有圖形項(xiàng)即將要移動(dòng);第二次phase的值為1,這時(shí)執(zhí)行移動(dòng)。下面我們看一個(gè)例子。
我們?cè)?/span>myitem.h中的protected中聲明函數(shù):void advance(int phase);
然后在myitem.cpp中對(duì)其進(jìn)行定義:
void MyItem::advance(int phase) { if(!phase) return;??//如果phase0,則返回 moveBy(0,10); } 在到main.cpp中添加以下代碼:
QTimer timer; QObject::connect(&timer, SIGNAL(timeout()),scene, SLOT(advance())); timer.start(1000);
這時(shí)運(yùn)行程序,小方塊就會(huì)每秒下移一下。

(七)動(dòng)畫 其實(shí)實(shí)現(xiàn)圖形項(xiàng)的動(dòng)畫效果,也可以在不同的層面進(jìn)行。如果我們只想控制一兩個(gè)圖形項(xiàng)的動(dòng)畫,一般在場(chǎng)景或視圖中實(shí)現(xiàn)。但是要是想讓一個(gè)圖形項(xiàng)類的多個(gè)對(duì)象都進(jìn)行同樣的動(dòng)畫,那么我們就可以在圖形項(xiàng)類中進(jìn)行實(shí)現(xiàn)。我們先看一個(gè)例子。 myitem.cpp文件中的構(gòu)造函數(shù)中添加代碼:
MyItem::MyItem() { setFlag(QGraphicsItem::ItemIsFocusable); //圖形項(xiàng)可獲得焦點(diǎn) setFlag(QGraphicsItem::ItemIsMovable); //圖形項(xiàng)可移動(dòng) QGraphicsItemAnimation *anim = new QGraphicsItemAnimation; //新建動(dòng)畫類對(duì)象 anim->setItem(this);??//將該圖形項(xiàng)加入動(dòng)畫類對(duì)象中 QTimeLine *timeLine = new QTimeLine(1000);??//新建長(zhǎng)為1秒的時(shí)間線 timeLine->setLoopCount(0);??//動(dòng)畫循環(huán)次數(shù)為0,表示無(wú)限循環(huán) anim->setTimeLine(timeLine); //將時(shí)間線加入動(dòng)畫類對(duì)象中 anim->setRotationAt(0.5,180); //在動(dòng)畫時(shí)間的一半時(shí)圖形項(xiàng)旋轉(zhuǎn)180 anim->setRotationAt(1,360);??//在動(dòng)畫執(zhí)行完時(shí)圖形項(xiàng)旋轉(zhuǎn)360 timeLine->start();??//開(kāi)始動(dòng)畫 }

這時(shí)執(zhí)行程序,效果如下:
小方塊會(huì)在一秒內(nèi)旋轉(zhuǎn)一圈。我們這里使用了QGraphicsItemAnimation動(dòng)畫類和QTimeLine時(shí)間線類,關(guān)于這些內(nèi)容我們會(huì)在后面的動(dòng)畫框架中細(xì)講,所以在這里就不再介紹。


(八)右鍵菜單 圖形項(xiàng)支持右鍵菜單,不過(guò)QGraphicsItem類并不是從QObject類繼承而來(lái)的,所以它默認(rèn)不能使用信號(hào)和槽機(jī)制,為了能使用信號(hào)和槽,我們需要將我們的MyItem類進(jìn)行多重繼承。 myitem.h中,將MyItem類改為
class MyItem : public QObject, publicQGraphicsItem { Q_OBJECT? ? //進(jìn)行宏定義 … … }
這樣我們就可以使用信號(hào)和槽機(jī)制了,這時(shí)我們?cè)谙旅嫣砑右粋€(gè)槽:
public slots: void moveTo(){setPos(0,0);}
因?yàn)槠鋵?shí)現(xiàn)的功能很簡(jiǎn)單,我們?cè)诼暶魉耐瑫r(shí)進(jìn)行了定義,就是讓圖形項(xiàng)移動(dòng)到(0,0)點(diǎn)。 然后我們?cè)?/span>protected中聲明右鍵菜單事件處理函數(shù):
voidcontextMenuEvent(QGraphicsSceneContextMenuEvent *event);
最后我們?cè)?/span>myitem.cpp文件中對(duì)該事件處理函數(shù)進(jìn)行定義:
voidMyItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) { QMenu menu; QAction *action = menu.addAction("moveTo(0,0)"); connect(action,SIGNAL(triggered()),this,SLOT(moveTo())); menu.exec(event->screenPos()); //在按下鼠標(biāo)左鍵的地方彈出菜單 }
這里我們只是設(shè)置了一個(gè)菜單,當(dāng)按下該菜單是,圖形項(xiàng)移動(dòng)到(0,0)點(diǎn)。 我們運(yùn)行程序,效果如下:



結(jié)語(yǔ)
? ?這一節(jié)先介紹了圖形項(xiàng)的相關(guān)內(nèi)容,而場(chǎng)景、視圖等內(nèi)容放到下一節(jié)來(lái)講。



涉及到的源碼:??graphicsView01.zip?(2.9 KB, 下載次數(shù): 30)??graphicsView02.zip?(2.54 KB, 下載次數(shù): 23)?


與50位技術(shù)專家面對(duì)面20年技術(shù)見(jiàn)證,附贈(zèng)技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的[Qt教程] 第19篇 2D绘图(九)图形视图框架(上)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。