当前位置:   article > 正文

QGraphicsPixmapItem与QGraphicsScene的编程实例 图标拖动渐变效果_ct bannerrect = qrect(option.rect.x(), option.rect

ct bannerrect = qrect(option.rect.x(), option.rect.y(), pixmap_width, label_

大家好,又见面了,我是全栈君,祝每个程序员都可以多学几门语言。

应大家的要求,还是把完整的project文件贴出来,大家省点事:http://www.kuaipan.cn/file/id_48923272389086450.htm

先看看执行效果,我用的群创7寸屏,主机是mini2440,分辨率是800*480,程序写比較粗糙,但对刚開始学习的人还是有一点启示,大家一起进步。

qt中提供了QGphicsView,QGraphicsScene,QGraphicsItem,QGraphicsPixmapItem是QGraphicsItem的子类

分辨创建它们的实例:view,scene,item,然后通过各自的方法scene->addItem(item);view->setScene(scene);就能够达到类似下图的效果,想要进一步定制,则要继承QGraphicsItem或QGraphicsPixmapItem,然后重写paint()、boundingRect()等方法,此外假设还想要获取鼠标事件,重写mousePressEvent等事件就好了,注意,一旦重写了mousePressEvent方法,就以为了qt不会再自己主动处理item的不论什么press事件了,能够在你重写的mousePressEvent方法中最后加入�QGraphicsItem::mousePressEvent(event);解决问题,就是说你获取到了鼠标事件,可是依旧让qt处理这个鼠标事件。

程序中的item能够水平拖动,拖动的同一时候图标大小会渐变,中间最大,两边渐小。

图1

图2

图3

以下是源程序文件夹结构:

mainwindow.h与main.cpp是qt自己主动产生的代码,我没有产生窗体ui

myscene.h与某与scene.cpp是定义了类MyScene,继承自QGraphicsScene,我的目的是要获取其鼠标事件

nodeui.h与nodeui.cpp是定义了类NodeUI,继承自QGraphicsPixmapItem,目的相当多。

以下详细的源文件:myscene.h与myscene.cpp相对简单,就实现了一个功能

myscene.h

  1. #ifndef MYSCENE_H
  2. #define MYSCENE_H
  3. #include <QGraphicsScene>
  4. class MyScene : public QGraphicsScene
  5. {
  6. Q_OBJECT
  7. public:
  8. explicit MyScene(QObject *parent = 0);
  9. private:
  10. void mouseMoveEvent(QGraphicsSceneMouseEvent *event);
  11. void mousePressEvent(QGraphicsSceneMouseEvent *event);
  12. void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
  13. signals:
  14. void isMoving(QPointF &pos);
  15. public slots:
  16. private:
  17. QPointF beforePos;
  18. QPointF releasePos;
  19. };
  20. #endif // MYSCENE_H

myscene.cpp

  1. #include "myscene.h"
  2. #include <QGraphicsSceneMouseEvent>
  3. #include <QPointF>
  4. #include <QDebug>
  5. MyScene::MyScene(QObject *parent) :
  6. QGraphicsScene(parent)
  7. {
  8. }
  9. void MyScene::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
  10. {
  11. //QPointF pos = event->scenePos();
  12. QPointF pos(event->scenePos().x()-beforePos.x(),event->scenePos().y()-beforePos.y());
  13. emit isMoving(pos);
  14. //qDebug()<<"x:"<<pos.x()<<"y:"<<pos.y();
  15. }
  16. void MyScene::mousePressEvent(QGraphicsSceneMouseEvent *event)
  17. {
  18. beforePos = event->scenePos();
  19. }
  20. void MyScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
  21. {
  22. releasePos = event->scenePos();
  23. }

再看nodeui.h与nodeui.cpp,在原来的QGraphicsPixmapItem基础上又假如了点自己的东西

  1. #ifndef NODEUI_H
  2. #define NODEUI_H
  3. #include <QGraphicsPixmapItem>
  4. #include <QGraphicsItem>
  5. #include <QStyleOptionGraphicsItem>
  6. #include <QPainter>
  7. #include <QGraphicsSceneMouseEvent>
  8. #include <QPointF>
  9. class NodeUI : public QObject,public QGraphicsPixmapItem
  10. {
  11. Q_OBJECT
  12. public:
  13. NodeUI();
  14. NodeUI(QString &file,QString &text,int imagesize=80);
  15. //setup function
  16. void setMyPixmap(QString &file,int size);
  17. void setMyText(QString &text);
  18. QString getMyText();
  19. //virtual function
  20. QRectF boundingRect() const;
  21. QPainterPath shape() const;
  22. signals:
  23. void nodeIsMoving(QPointF &pos);
  24. void nodeIsPressed();
  25. protected:
  26. void mousePressEvent(QGraphicsSceneMouseEvent *event);
  27. void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);
  28. private:
  29. //QString myImage;
  30. QString myText;
  31. };
  32. #endif // NODEUI_H

nideui.cpp

  1. #include "nodeui.h"
  2. #include <QPixmap>
  3. #include <iostream>
  4. #include <QDebug>
  5. NodeUI::NodeUI()
  6. {
  7. }
  8. /*note: imagesize = 80 is in the nodeui.h*/
  9. NodeUI::NodeUI(QString &file,QString &text,int imagesize)
  10. {
  11. setMyText(text);
  12. setMyPixmap(file,imagesize);
  13. }
  14. void NodeUI::setMyText(QString &text)
  15. {
  16. myText = text;
  17. }
  18. void NodeUI::setMyPixmap(QString &file,int size)
  19. {
  20. //myImage = file;
  21. QPixmap pixmap;
  22. pixmap.load(file);
  23. pixmap= pixmap.scaled(size,size,Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
  24. setPixmap(pixmap);
  25. }
  26. QRectF NodeUI::boundingRect() const
  27. {
  28. QRect rect = this->pixmap().rect();
  29. //return QRectF(rect);
  30. return QRectF(0,0,rect.width(),rect.width()+15);
  31. }
  32. void NodeUI::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
  33. QWidget *widget)
  34. {
  35. QPixmap pixmap = this->pixmap();
  36. QRect rect = pixmap.rect();
  37. painter->drawPixmap(rect,pixmap);
  38. //print name,calculate the text's heigh & width for center layout
  39. QPen pen(Qt::black);
  40. painter->setPen(pen);
  41. painter->setRenderHint(QPainter::Antialiasing);
  42. QFont font("Verdana",8, QFont::Normal);
  43. painter->setFont(font);
  44. painter->drawText(QRectF(0,rect.height(),rect.width(),15),Qt::AlignCenter,myText);
  45. if (option->state & QStyle::State_Sunken)
  46. {
  47. QRectF rect1 = boundingRect();
  48. //QPen pen(Qt::darkGreen);
  49. painter->setPen(QPen(Qt::darkGreen));
  50. }else
  51. {
  52. }
  53. }
  54. QPainterPath NodeUI::shape() const
  55. {
  56. QRectF rect = boundingRect();
  57. QPainterPath path;
  58. path.addRoundRect(rect, 5,5);
  59. return path;
  60. }
  61. void NodeUI::mousePressEvent(QGraphicsSceneMouseEvent *event)
  62. {
  63. emit nodeIsPressed();
  64. qDebug()<<"pressed";
  65. QGraphicsItem::mousePressEvent(event);
  66. }
  67. void NodeUI::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
  68. {
  69. update(boundingRect());
  70. QGraphicsItem::mouseReleaseEvent(event);
  71. }
  72. QString NodeUI::getMyText()
  73. {
  74. return myText;
  75. }

最后是scene与item的文件mainwindow.cpp,继承了QMainWindow,作用就是画一个应用程序框架

mainwindow.h

  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3. #include <QtGui/QMainWindow>
  4. #include <QGraphicsView>
  5. #include <QGraphicsScene>
  6. #include <QPointF>
  7. #include "nodeui.h"
  8. #include "myscene.h"
  9. #include <QMap>
  10. class MainWindow : public QMainWindow
  11. {
  12. Q_OBJECT
  13. public:
  14. MainWindow(QWidget *parent = 0);
  15. ~MainWindow();
  16. NodeUI *selectedNodeUI();
  17. bool isNodeUiClicked();
  18. void nodeUiSizeAdjust();
  19. //var
  20. protected:
  21. private:
  22. void GetScreenInfo();
  23. QGraphicsView *view;
  24. //QGraphicsScene *scene;
  25. MyScene *scene;
  26. //instead of (NodeUI *nodeui;)&(QPointF nodeUiPos;)
  27. //眼下弃用,因为QMap的顺序无法人为设定,依照内部key自己主动升序
  28. //QMap<NodeUI*,QPointF>nodeUiMaps;
  29. //NodeUI *currentNodeUI;
  30. //nodeui pressed or released
  31. volatile bool mPressed;
  32. QList<NodeUI*> nodeUiLists;
  33. QList<QPointF> nodeUiPosLists;
  34. QList<QPixmap> nodeUiPixmapLists;
  35. /*
  36. struct {
  37. QList<NodeUI*> nodelists;
  38. QList<QPointF> poslists;
  39. }ss;
  40. */
  41. //弃用
  42. NodeUI *nodeui;
  43. QPointF nodeUiPos;
  44. //sceen size info;
  45. qint16 sceenSizeX;
  46. qint16 sceenSizeY;
  47. private slots:
  48. void isMoving(QPointF &pos);
  49. void isPressed();
  50. void isReleased();
  51. void selectionChanged();
  52. signals:
  53. void nodeUiClicked(NodeUI* node);
  54. };
  55. #endif // MAINWINDOW_H

mainwindow.cpp

  1. #include "mainwindow.h"
  2. #include <QDesktopWidget>
  3. #include <QApplication>
  4. #include <QPixmap>
  5. #include <QGraphicsItem>
  6. #include <QMouseEvent>
  7. #include <QWidget>
  8. #include <QGraphicsPixmapItem>
  9. #include <QMessageBox>
  10. #include <QDebug>
  11. const qreal MY_NODEUI_POS_Y = 200;
  12. const qreal MY_NODEUI_DIS = 110;
  13. const qreal MY_NODEUI_STA = 90;
  14. const int MYNODEUI_SIZE = 100;
  15. const int MYNODEUI_SIZE_M = 20;
  16. const int SCREEN_SIZE = 800;
  17. MainWindow::MainWindow(QWidget *parent)
  18. : QMainWindow(parent)
  19. {
  20. //初始化
  21. mPressed = false;
  22. //get windows size
  23. GetScreenInfo();
  24. view = new QGraphicsView;
  25. scene = new MyScene();
  26. scene->setSceneRect(0,0,800,480);
  27. //new
  28. QString file;
  29. QString text;
  30. QPointF pos;
  31. NodeUI* node;
  32. //HOME:1
  33. file = QString(":/images/home.png");
  34. text = QString("Home");
  35. pos = QPointF(MY_NODEUI_STA,MY_NODEUI_POS_Y);
  36. node = new NodeUI(file,text,MYNODEUI_SIZE);
  37. node->setPos(pos);
  38. nodeUiLists.append(node);
  39. nodeUiPosLists.append(pos);
  40. nodeUiPixmapLists.append(node->pixmap());
  41. /*
  42. here cannot delete node!!!!!!!!!!!!!!!
  43. delete node;
  44. */
  45. //VIDIO:2
  46. file = QString(":/images/securitycamera.png");
  47. text = QString("Vidio");
  48. pos = QPointF(MY_NODEUI_STA+MY_NODEUI_DIS*1,MY_NODEUI_POS_Y);
  49. node = new NodeUI(file,text,MYNODEUI_SIZE);
  50. node->setPos(pos);
  51. nodeUiLists.append(node);
  52. nodeUiPosLists.append(pos);
  53. nodeUiPixmapLists.append(node->pixmap());
  54. //APPLICATION:3
  55. file = QString(":/images/application.png");
  56. text = QString("Application");
  57. pos = QPointF(MY_NODEUI_STA+MY_NODEUI_DIS*2,MY_NODEUI_POS_Y);
  58. node = new NodeUI(file,text,MYNODEUI_SIZE);
  59. node->setPos(pos);
  60. nodeUiLists.append(node);
  61. nodeUiPosLists.append(pos);
  62. nodeUiPixmapLists.append(node->pixmap());
  63. //NETWORK:4
  64. file = QString(":/images/network-2.png");
  65. text = QString("Network");
  66. pos = QPointF(MY_NODEUI_STA+MY_NODEUI_DIS*3,MY_NODEUI_POS_Y);
  67. node = new NodeUI(file,text,MYNODEUI_SIZE);
  68. node->setPos(pos);
  69. nodeUiLists.append(node);
  70. nodeUiPosLists.append(pos);
  71. nodeUiPixmapLists.append(node->pixmap());
  72. //COMPUTER:5
  73. file = QString(":/images/smartphone.png");
  74. text = QString("Phone");
  75. pos = QPointF(MY_NODEUI_STA+MY_NODEUI_DIS*4,MY_NODEUI_POS_Y);
  76. node = new NodeUI(file,text,MYNODEUI_SIZE);
  77. node->setPos(pos);
  78. nodeUiLists.append(node);
  79. nodeUiPosLists.append(pos);
  80. nodeUiPixmapLists.append(node->pixmap());
  81. //CUSTOMIZE:5
  82. file = QString(":/images/customize.png");
  83. text = QString("Setting");
  84. pos = QPointF(MY_NODEUI_STA+MY_NODEUI_DIS*5,MY_NODEUI_POS_Y);
  85. node = new NodeUI(file,text,MYNODEUI_SIZE);
  86. node->setPos(pos);
  87. nodeUiLists.append(node);
  88. nodeUiPosLists.append(pos);
  89. nodeUiPixmapLists.append(node->pixmap());
  90. //又一次计算UiSize
  91. nodeUiSizeAdjust();
  92. int i = 0;
  93. foreach(NodeUI* node_temp,nodeUiLists)
  94. {
  95. node_temp->setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsSelectable);
  96. qDebug()<<"name:"<<node_temp->getMyText()<<nodeUiPosLists.at(i);
  97. scene->addItem(node_temp);
  98. i++;
  99. }
  100. //用于button的单机
  101. view->setScene(scene);
  102. //set drag mode
  103. //view->setDragMode(QGraphicsView::RubberBandDrag);
  104. view->setRenderHints(QPainter::Antialiasing);
  105. //no menu
  106. view->setContextMenuPolicy(Qt::NoContextMenu);
  107. view->setBackgroundBrush(QImage(":/images/shuibo2.jpg"));
  108. //view->setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
  109. //view->setCacheMode(QGraphicsView::CacheBackground);
  110. setCentralWidget(view);
  111. setWindowTitle(tr("Main Window"));
  112. }
  113. //槽,当scene鼠标拖拽是运行
  114. //控制UI图标的水平
  115. void MainWindow::isMoving(QPointF &pos)
  116. {
  117. int i=0;
  118. if(mPressed){
  119. foreach(NodeUI* node,nodeUiLists)
  120. {
  121. node->setPos(nodeUiPosLists.at(i).x()+pos.x(),MY_NODEUI_POS_Y);
  122. i++;
  123. }
  124. nodeUiSizeAdjust();
  125. }
  126. }
  127. //槽,当nodeui鼠标按下时运行,调用selectedNodeUI函数,更新currentNodeUI变量
  128. //除此之外,selectionChanged()也是一个槽,由scene调用
  129. void MainWindow::isPressed()
  130. {
  131. selectionChanged();
  132. mPressed = true;
  133. }
  134. //槽,当nodeui鼠标释放时运行
  135. //应当设置标志位,让UI图片停止对鼠标拖动事件的响应
  136. void MainWindow::isReleased()
  137. {
  138. mPressed = false;
  139. if(isNodeUiClicked())
  140. qDebug()<<"clicked";
  141. qDebug()<<"release";
  142. }
  143. //槽,当scene的selectedItem变化时,发送同名信号到此槽
  144. void MainWindow::selectionChanged()
  145. {
  146. int i=0,j=0;
  147. QList<QGraphicsItem *> items = scene->selectedItems();
  148. if (items.count() == 1) {
  149. //当前所选择的UI图标的坐标
  150. QPointF pos = items.first()->pos();
  151. NodeUI* node_temp = dynamic_cast<NodeUI *>(items.first());
  152. qDebug()<<"items.x:"<<pos.x()<<"items.y:"<<pos.y();
  153. foreach(NodeUI* node,nodeUiLists)
  154. {
  155. if(node == node_temp)
  156. break;
  157. i++;
  158. }
  159. j=i;
  160. i=0;
  161. foreach(QPointF ppos,nodeUiPosLists)
  162. {
  163. nodeUiPosLists[i].setX((i-j)*MY_NODEUI_DIS+pos.x());
  164. nodeUiPosLists[i].setY(MY_NODEUI_POS_Y);
  165. i++;
  166. }
  167. } else {
  168. return;
  169. }
  170. }
  171. //推断是否Nodeui接收的是否是单击信号。
  172. //推断根据是当前单击的nodeui对象的pos与存储在nodeUiPosListsd的位置比較,相等则为单击
  173. bool MainWindow::isNodeUiClicked()
  174. {
  175. int i=-1;
  176. QList<QGraphicsItem *> items = scene->selectedItems();
  177. if (items.count() == 1) {
  178. QPointF pos = items.first()->pos();
  179. NodeUI* node_temp = dynamic_cast<NodeUI *>(items.first());
  180. if(pos ==nodeUiPosLists.at(i)){
  181. //emit nodeUiClicked(node_temp);
  182. QMessageBox::information(this,"New Window","will open : "+node_temp->getMyText());
  183. return true;
  184. }
  185. }
  186. return false;
  187. }
  188. void MainWindow::nodeUiSizeAdjust()
  189. {
  190. quint16 i=0;
  191. foreach(NodeUI* node,nodeUiLists)
  192. {
  193. //qDebug()<<"i= "<<i;
  194. QPointF pos=node->pos();
  195. pos.setX(node->pos().x()+MYNODEUI_SIZE/2);
  196. //pos.setX(node->pos().x()+node->pixmap().width());
  197. if(pos.x()>=0 && pos.x()<=SCREEN_SIZE/2)
  198. {
  199. //(MYNODEUI_SIZE-MYNODEUI_SIZE_M)/(SCREEN_SIZE/2)==(size-20)/pos.x()
  200. quint16 size=pos.x()/5+20;
  201. QPixmap pixmap = nodeUiPixmapLists.at(i);
  202. //QPixmap pixmap = nodeUiLists.at(i)->pixmap();
  203. pixmap = pixmap.scaled(size,size,Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
  204. nodeUiLists[i]->setPixmap(pixmap);
  205. }
  206. //if(pos.x()>SCREEN_SIZE/2 && pos.x()<=SCREEN_SIZE)
  207. if(pos.x()>SCREEN_SIZE/2 && pos.x()<=SCREEN_SIZE+10)
  208. {
  209. //(MYNODEUI_SIZE-MYNODEUI_SIZE_M)/(SCREEN_SIZE/2)==(size-20)/pos.x()
  210. quint16 size=(SCREEN_SIZE-pos.x())/5+20;
  211. QPixmap pixmap = nodeUiPixmapLists.at(i);
  212. //QPixmap pixmap = nodeUiLists.at(i)->pixmap();
  213. pixmap = pixmap.scaled(size,size,Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
  214. nodeUiLists[i]->setPixmap(pixmap);
  215. }
  216. i++;
  217. }
  218. }
  219. MainWindow::~MainWindow()
  220. {
  221. }
  222. //获取设备分辨率的呢个信息
  223. void MainWindow::GetScreenInfo()
  224. {
  225. QDesktopWidget* desktopWidget = QApplication::desktop();
  226. //获取可用桌面大小
  227. //QRect deskRect = desktopWidget->availableGeometry();
  228. //获取设备屏幕大小
  229. QRect screenRect = desktopWidget->screenGeometry();
  230. sceenSizeX = screenRect.width();
  231. sceenSizeY = screenRect.height();
  232. //获取系统设置的屏幕个数(屏幕拷贝方式该值为1
  233. //g_nScreenCount = desktopWidget->screenCount();
  234. }

最后是main.cpp

实例化MainWindow

  1. #include <QtGui/QApplication>
  2. #include "mainwindow.h"
  3. int main(int argc, char *argv[])
  4. {
  5. QApplication a(argc, argv);
  6. MainWindow w;
  7. w.setWindowOpacity(1);
  8. w.setWindowFlags(Qt::FramelessWindowHint);
  9. w.setAttribute(Qt::WA_TranslucentBackground);
  10. w.show();
  11. //w.showFullScreen();
  12. return a.exec();
  13. }

大概都写了注解了,事实上看看一个名称也该大概了解其作用,写这程序时遇到的问题都记录在了前一篇qt学习笔记(四)中,记录一下,以备不时之需

 进群领取qt开发学习资料以及技术交流  在下方↓↓↓↓↓↓↓↓

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/118484.html原文链接:https://javaforall.cn

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/297436
推荐阅读
  

闽ICP备14008679号