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

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

生活随笔

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

编程问答

Qt 视图框架示例 Colliding Mice 的翻译

發(fā)布時(shí)間:2025/3/15 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt 视图框架示例 Colliding Mice 的翻译 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄名字

  • Qt 視圖框架示例 Colliding Mice 的翻譯
    • 簡(jiǎn)介:
    • Mouse Class 定義
    • Mouse Class 定義
    • The Main() 函數(shù)

Qt 視圖框架示例 Colliding Mice 的翻譯

簡(jiǎn)介:

該示例程序介紹了怎樣在Qt的視圖框架里創(chuàng)建動(dòng)畫以及沖突檢測(cè)。

視圖框架提供了QGraphicsScene class 場(chǎng)景類來(lái)管理2D圖形對(duì)象.一個(gè)QGraphicsView widget 來(lái)是顯示這些圖形項(xiàng),并且支持視圖的縮放和旋轉(zhuǎn)。

在該示例中, Mouse class 自定義了一些Mice 的圖形項(xiàng),main() 函數(shù)提供了應(yīng)用程序的窗體。

首先我們來(lái)學(xué)習(xí)Mouse 類是如何實(shí)現(xiàn)動(dòng)畫和沖突檢測(cè)的。然后我們學(xué)習(xí)main()函數(shù)是如何將mice 圖形項(xiàng)添加到場(chǎng)景中。

Mouse Class 定義

The mouse class繼承自QGraphicsItem. QGraphicsItem是視圖框架中所有圖形項(xiàng)的基類。它提供了一個(gè)輕量級(jí)的框架來(lái)創(chuàng)建用戶自定義的一些圖形項(xiàng)。

class Mouse : public QGraphicsItem{public:Mouse();QRectF boundingRect() const override;QPainterPath shape() const override;void paint(QPainter *painter, const QStyleOptionGraphicsItem *option,QWidget *widget) override;protected:void advance(int step) override;private:qreal angle = 0;qreal speed = 0;qreal mouseEyeDirection = 0;QColor color;};

當(dāng)我們創(chuàng)建自定義圖形項(xiàng)的時(shí)候,我們必須要重寫兩個(gè)虛函數(shù)
1、 boundingRect(), 繪圖的邊界
2、 paint(), 繪圖

我們還重寫了兩個(gè)函數(shù)shape()和advance().
1、shape():mice 圖形項(xiàng)的準(zhǔn)確形狀。默認(rèn)情況下,返回的是bounding rectangle.
2、advance():實(shí)現(xiàn)動(dòng)畫

Mouse Class 定義

構(gòu)造函數(shù):初始化一些私有變量

Mouse::Mouse() : color(QRandomGenerator::global()->bounded(256),QRandomGenerator::global()->bounded(256),QRandomGenerator::global()->bounded(256)){setRotation(QRandomGenerator::global()->bounded(360 * 16));}

這里我們用QRandomGenerator. 來(lái)實(shí)現(xiàn)Mice的不同膚色。
setRotation()來(lái)改變Mice 的方向。

QGraphicsScene 會(huì)在幀的推進(jìn)中會(huì)調(diào)用每一圖形項(xiàng)的advance()功能,這里我們重寫了這個(gè)advance()方法,于是Mice會(huì) 一幀幀的動(dòng)起來(lái)了。

void Mouse::advance(int step){if (!step)return;QLineF lineToCenter(QPointF(0, 0), mapFromScene(0, 0));if (lineToCenter.length() > 150) {qreal angleToCenter = std::atan2(lineToCenter.dy(), lineToCenter.dx());angleToCenter = normalizeAngle((Pi - angleToCenter) + Pi / 2);if (angleToCenter < Pi && angleToCenter > Pi / 4) {// Rotate leftangle += (angle < -Pi / 2) ? 0.25 : -0.25;} else if (angleToCenter >= Pi && angleToCenter < (Pi + Pi / 2 + Pi / 4)) {// Rotate rightangle += (angle < Pi / 2) ? 0.25 : -0.25;}} else if (::sin(angle) < 0) {angle += 0.25;} else if (::sin(angle) > 0) {angle -= 0.25;}

因?yàn)閍dvance()被調(diào)用兩次,第一次是step=0;然后是step=1;前一次不作任何動(dòng)作。同時(shí),我們要保證mice待在一個(gè)半徑是150像素的圓內(nèi)。

mapFromScene() 是完成從圖形項(xiàng)坐標(biāo)到場(chǎng)景坐標(biāo)的映射。const QList<QGraphicsItem *> dangerMice = scene()->items(QPolygonF()<< mapToScene(0, 0)<< mapToScene(-30, -50)<< mapToScene(30, -50));for (const QGraphicsItem *item : dangerMice) {if (item == this)continue;QLineF lineToMouse(QPointF(0, 0), mapFromItem(item, 0, 0));qreal angleToMouse = std::atan2(lineToMouse.dy(), lineToMouse.dx());angleToMouse = normalizeAngle((Pi - angleToMouse) + Pi / 2);if (angleToMouse >= 0 && angleToMouse < Pi / 2) {// Rotate rightangle += 0.5;} else if (angleToMouse <= TwoPi && angleToMouse > (TwoPi - Pi / 2)) {// Rotate leftangle -= 0.5;}}if (dangerMice.size() > 1 && QRandomGenerator::global()->bounded(10) == 0) {if (QRandomGenerator::global()->bounded(1))angle += QRandomGenerator::global()->bounded(1 / 500.0);elseangle -= QRandomGenerator::global()->bounded(1 / 500.0);}

然后我們要實(shí)現(xiàn)老鼠的碰撞的處理

speed += (-50 + QRandomGenerator::global()->bounded(100)) / 100.0;qreal dx = ::sin(angle) * 10;mouseEyeDirection = (qAbs(dx / 5) < 1) ? 0 : dx / 5;setRotation(rotation() + dx);setPos(mapToParent(0, -(3 + sin(speed) * 3)));}

最后,我們計(jì)算mice的速度,和方向然后設(shè)定一個(gè)新的坐標(biāo)。

QGraphicsItem::setPos() 函數(shù)會(huì)設(shè)定一個(gè)父窗體的坐標(biāo)系統(tǒng)的位置。

應(yīng)為圖形項(xiàng)是沒(méi)有父對(duì)象的,所以需要mapToParent() 將坐標(biāo)映射到需要設(shè)置的父窗體的坐標(biāo)系中。如果沒(méi)有設(shè)定父窗體,默認(rèn)是映射到場(chǎng)景的坐標(biāo)系中。

QRectF Mouse::boundingRect() const{qreal adjust = 0.5;return QRectF(-18 - adjust, -22 - adjust,36 + adjust, 60 + adjust);}

boundingRect() 定義了圖形項(xiàng)的矩形邊界。Qt中的視圖框架是通過(guò)該函數(shù)的返回值類決定是否需要重畫圖形項(xiàng)。

void Mouse::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *){// Bodypainter->setBrush(color);painter->drawEllipse(-10, -20, 20, 40);// Eyespainter->setBrush(Qt::white);painter->drawEllipse(-10, -17, 8, 8);painter->drawEllipse(2, -17, 8, 8);// Nosepainter->setBrush(Qt::black);painter->drawEllipse(QRectF(-2, -22, 4, 4));// Pupilspainter->drawEllipse(QRectF(-8.0 + mouseEyeDirection, -17, 4, 4));painter->drawEllipse(QRectF(4.0 + mouseEyeDirection, -17, 4, 4));// Earspainter->setBrush(scene()->collidingItems(this).isEmpty() ? Qt::darkYellow : Qt::red);painter->drawEllipse(-17, -12, 16, 16);painter->drawEllipse(1, -12, 16, 16);// TailQPainterPath path(QPointF(0, 20));path.cubicTo(-5, 22, -5, 22, 0, 25);path.cubicTo(5, 27, 5, 32, 0, 30);path.cubicTo(-5, 32, -5, 42, 0, 35);painter->setBrush(Qt::NoBrush);painter->drawPath(path);}

paint()函數(shù)執(zhí)行實(shí)際的圖形項(xiàng)的繪制。繪制時(shí)的坐標(biāo)系都是圖形項(xiàng)自身的坐標(biāo)系。

mice 的耳朵在碰撞是會(huì)顯示紅色。沒(méi)有碰撞時(shí)是灰黑色。

在Qt的視圖框架里通過(guò)shape-shape 交互來(lái)檢測(cè)識(shí)別碰撞沖突,所以shape()函數(shù)里返回的shape值必須要準(zhǔn)確。

QPainterPath Mouse::shape() const{QPainterPath path;path.addRect(-10, -20, 20, 40);return path;}

當(dāng)shapes 變得復(fù)雜的時(shí)候,shape-shape 重疊檢測(cè)也會(huì)變得復(fù)雜,這會(huì)耗費(fèi)計(jì)算的時(shí)間。重寫collidesWithItem()該函數(shù)可以自定義沖突的算法。

接著我們來(lái)看main()函數(shù)

The Main() 函數(shù)

int main(int argc, char **argv){QApplication app(argc, argv);

首先我們創(chuàng)建一個(gè)應(yīng)用程序,并且創(chuàng)建一個(gè)場(chǎng)景。

QGraphicsScene scene;
scene.setSceneRect(-300, -300, 600, 600);

QGraphicsScene提供了放置QGraphicsItems 的一個(gè)容器。該容器提供了一些函數(shù)方法來(lái)更好的顯示,管理圖形項(xiàng)。

當(dāng)我們創(chuàng)建了一個(gè)場(chǎng)景,我們推介設(shè)定該場(chǎng)景的大小。若過(guò)沒(méi)有設(shè)定大小,場(chǎng)景的大小會(huì)隨著圖形項(xiàng)的增加,而不斷增大。

場(chǎng)景會(huì)給每一個(gè)圖形項(xiàng)一個(gè)索引號(hào),也可以不設(shè)定索引號(hào)。索引號(hào)可以快速的定位到圖形項(xiàng)。

scene.setItemIndexMethod(QGraphicsScene::NoIndex);

QgrapbhicsScene使用下標(biāo)來(lái)高效的管理item的位置,默認(rèn)的使用BSP樹,適用于一個(gè)大型的場(chǎng)景,其中的item都是靜止不變的,可以選擇調(diào)用setItemIndexMethod().來(lái)禁用下標(biāo),可是查看itemIndexMethod來(lái)獲取更多的信息

for (int i = 0; i < MouseCount; ++i) {Mouse *mouse = new Mouse;mouse->setPos(::sin((i * 6.28) / MouseCount) * 200,::cos((i * 6.28) / MouseCount) * 200);scene.addItem(mouse);}

//創(chuàng)建mice 圖形項(xiàng)

for (int i = 0; i < MouseCount; ++i) {Mouse *mouse = new Mouse;mouse->setPos(::sin((i * 6.28) / MouseCount) * 200,::cos((i * 6.28) / MouseCount) * 200);scene.addItem(mouse);}

//然后將這些圖形項(xiàng)添加到場(chǎng)景中

QGraphicsView view(&scene);view.setRenderHint(QPainter::Antialiasing);view.setBackgroundBrush(QPixmap(":/images/cheese.jpg"));

為了能夠歐看到場(chǎng)景,我們需要?jiǎng)?chuàng)建一個(gè)場(chǎng)景的窗體,QGraphicsView 類 可以提供一個(gè)自帶滾動(dòng)條的窗體。我們確保圖形的渲染是抗鋸齒的。通過(guò)背景刷繪制一個(gè)背景。

view.setCacheMode(QGraphicsView::CacheBackground);view.setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);view.setDragMode(QGraphicsView::ScrollHandDrag);

設(shè)置緩存機(jī)制。QGraphicsView 可以預(yù)渲染像素化的圖形。

設(shè)定拖拽模式。ScrollHandDrag 該模式下,當(dāng)鼠標(biāo)拖拽時(shí)會(huì)變?yōu)槭中?#xff0c;同時(shí)滾動(dòng)條會(huì)隨之變化。

view.setWindowTitle(QT_TRANSLATE_NOOP(QGraphicsView, "Colliding Mice"));view.resize(400, 300);view.show();QTimer timer;QObject::connect(&timer, &QTimer::timeout, &scene, &QGraphicsScene::advance);timer.start(1000 / 33);return app.exec();}

最后設(shè)定窗體的標(biāo)題,創(chuàng)建一個(gè)定時(shí)器,設(shè)定定時(shí)器的超時(shí)事件來(lái)調(diào)用場(chǎng)景的幀的步進(jìn)。

總結(jié)

以上是生活随笔為你收集整理的Qt 视图框架示例 Colliding Mice 的翻译的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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