QT与很多GUI库不同(如MFC),它不能随时随地地在界面上画图,只能在界面类的painterEvent中画图,如此一来,想在绘制QT界面时使用状态模式(GOF的23种设计模式之一)就有点困难了,作为解决方案,我先把要界面上的图片绘制在一张图片上(QPixmap),然后再在painterEvent中将Pixmap“画”到界面上。以下是这种方法的一个小例子。

截图:

源代码:

  1. #include <QtGui>
  2. //状态类的基类,定义了各个公用接口,
  3. //其中,SetPixmap是一个纯虚接口
  4. class BasePen
  5. {
  6. protected:
  7. //这三个类成员理应是BasePen的私有成员,然后通过接口访问
  8. //我这里为了方便,直接把它们设为保护成员了
  9. QPixmap m_Pixmap;
  10. QPoint m_StartPoint;
  11. QPoint m_EndPoint;
  12. virtual void SetPixmap() = 0;
  13. public:
  14. BasePen()
  15. {
  16. m_StartPoint = m_EndPoint = QPoint(0, 0);
  17. m_Pixmap = QPixmap(500, 500);
  18. }
  19. void SetStartPoint(QPoint point) { m_StartPoint = point; }
  20. void SetEndPoint(QPoint point)
  21. {
  22. m_EndPoint = point;
  23. SetPixmap();
  24. }
  25. QPixmap GetPixmap() { return m_Pixmap; }
  26. };
  27. //矩形类,在界面上画一个红色的矩形
  28. class RectPen : public BasePen
  29. {
  30. protected:
  31. void SetPixmap()
  32. {
  33. m_Pixmap.fill(Qt::white);
  34. QPainter painter(&m_Pixmap);
  35. QRect rect(m_StartPoint, m_EndPoint);
  36. painter.setPen(Qt::red);
  37. painter.drawRect(rect);
  38. }
  39. };
  40. //直线类,在界面上画一条蓝色的直线
  41. class LinePen : public BasePen
  42. {
  43. protected:
  44. void SetPixmap()
  45. {
  46. m_Pixmap.fill(Qt::white);
  47. QPainter painter(&m_Pixmap);
  48. painter.setPen(Qt::blue);
  49. painter.drawLine(m_StartPoint, m_EndPoint);
  50. }
  51. };
  52. //圆形类,在界面上画一个绿色的椭圆
  53. class CirclePen : public BasePen
  54. {
  55. protected:
  56. void SetPixmap()
  57. {
  58. m_Pixmap.fill(Qt::white);
  59. QPainter painter(&m_Pixmap);
  60. QRect rect(m_StartPoint, m_EndPoint);
  61. painter.setPen(Qt::green);
  62. painter.drawEllipse(rect);
  63. }
  64. };
  65. class Widget : public QWidget
  66. {
  67. Q_OBJECT
  68. private:
  69. bool m_MouseDown;
  70. BasePen *m_BasePen;
  71. RectPen *m_RectPen;
  72. LinePen *m_LinePen;
  73. CirclePen *m_CirclePen;
  74. //在界面上放三个按钮,用来控制画图状态
  75. QRadioButton *m_LineButton;
  76. QRadioButton *m_RectButton;
  77. QRadioButton *m_CircleButton;
  78. protected:
  79. void mousePressEvent(QMouseEvent *event);
  80. void mouseMoveEvent(QMouseEvent *event);
  81. void mouseReleaseEvent(QMouseEvent *event);
  82. void paintEvent(QPaintEvent *event);
  83. public:
  84. Widget(QWidget *parent = 0);
  85. ~Widget();
  86. private slots:
  87. void ClickedLineButton() { m_BasePen = m_LinePen; }
  88. void ClickedRectButton() { m_BasePen = m_RectPen; }
  89. void ClickedCircleButton() { m_BasePen = m_CirclePen; }
  90. };
  91. Widget::Widget(QWidget *parent /* = 0 */)
  92. : QWidget(parent)
  93. {
  94. m_MouseDown = false;
  95. m_RectPen = new RectPen;
  96. m_LinePen = new LinePen;
  97. m_CirclePen = new CirclePen;
  98. m_LineButton = new QRadioButton("Line", this);
  99. m_RectButton = new QRadioButton("Rect", this);
  100. m_CircleButton = new QRadioButton("Circle", this);
  101. m_LineButton->move(10, 10);
  102. m_RectButton->move(100, 10);
  103. m_CircleButton->move(200, 10);
  104. connect(m_LineButton, SIGNAL(clicked()), this, SLOT(ClickedLineButton()));
  105. connect(m_RectButton, SIGNAL(clicked()), this, SLOT(ClickedRectButton()));
  106. connect(m_CircleButton, SIGNAL(clicked()), this, SLOT(ClickedCircleButton()));
  107. m_BasePen = m_LinePen;
  108. m_LineButton->setChecked(true);
  109. setFixedSize(500, 500);
  110. }
  111. Widget::~Widget()
  112. {
  113. delete m_LinePen;
  114. delete m_RectPen;
  115. delete m_CirclePen;
  116. }
  117. void Widget::mousePressEvent(QMouseEvent *event)
  118. {
  119. if( event->button() == Qt::LeftButton )
  120. {
  121. m_MouseDown = true;
  122. m_BasePen->SetStartPoint(event->pos());
  123. }
  124. }
  125. void Widget::mouseMoveEvent(QMouseEvent *event)
  126. {
  127. if( m_MouseDown )
  128. {
  129. m_BasePen->SetEndPoint(event->pos());
  130. update();
  131. }
  132. }
  133. void Widget::mouseReleaseEvent(QMouseEvent *event)
  134. {
  135. if( event->button() == Qt::LeftButton )
  136. {
  137. m_MouseDown = false;
  138. }
  139. }
  140. void Widget::paintEvent(QPaintEvent *event)
  141. {
  142. QPixmap temp = m_BasePen->GetPixmap();
  143. QPainter painter(this);
  144. painter.drawPixmap(0, 0, temp);
  145. }
  146. #include "main.moc"
  147. int main(int argc, char **argv)
  148. {
  149. QApplication app(argc, argv);
  150. Widget *ww = new Widget;
  151. ww->show();
  152. return app.exec();
  153. }

http://blog.csdn.net/small_qch/article/details/7632226

QT:使用“状态模式”绘制界面的更多相关文章

  1. Android自定义控件7--自定义开关--绘制界面内容

    本文实现全自定义控件--自定义开关 本文地址:http://www.cnblogs.com/wuyudong/p/5922316.html,转载请注明源地址. 自定义开关 (View),本文完成下面内 ...

  2. iOS - 在工程中试玩状态模式

    做了一个项目,项目中一个藏品详情界面针对不同用户,和用户所处于的状态的不同,展示的效果和操作的权限都会不同.想到了状态模式,从来没有用过,赶紧学一下然后用一用.期待兴奋 看了这么多的博客,终于找到一个 ...

  3. 【状态模式】 State Pattern

    我们先设计一个场景,饮料自动售卖机,来设计一下它的出售流程. 流程图中,我们可把这个过程看成几个状态: 投币状态,选择饮料状态,售出状态,出售完毕状态. ,有了这个四个状态,我们设计一下界面(很粗略) ...

  4. 【转】设计模式 ( 十七) 状态模式State(对象行为型)

    设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...

  5. (转)Qt Model/View 学习笔记 (一)——Qt Model/View模式简介

    Qt Model/View模式简介 Qt 4推出了一组新的item view类,它们使用model/view结构来管理数据与表示层的关系.这种结构带来的 功能上的分离给了开发人员更大的弹性来定制数据项 ...

  6. 设计模式 ( 十八 ):State状态模式 -- 行为型

    1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ellse语句来做状态判断来进行不同情况的处理.但是对 ...

  7. 设计模式 ( 十七) 状态模式State(对象行为型)

    设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...

  8. JavaScript中的设计模式:状态模式

    前几天写了一个贪吃蛇小游戏,正好用到了状态模式. 定义 当一个对象内部状态发生改变时候,会导致其行为的改变,这看起来像是改变了对象. 简单的例子 如果一个函数要更具某一个对象的状态来判断该对象应该执行 ...

  9. Java设计模式(19)状态模式(State模式)

    State的定义:不同的状态,不同的行为:或者说,每个状态有着相应的行为. 何时使用状态模式 State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If else ...

随机推荐

  1. Ubuntu14.04安装PostpreSQL9.3.5记录

    安装参考:http://www.postgresql.org/download/linux/ubuntu/ y@y:~$ sudo apt-get install postgresql-9.3 pos ...

  2. asm_c515c.uew

    /L20"ASM for C515C" Nocase Line Comment = ; String Chars = "' DisableMLS File Extensi ...

  3. 认识元数据和IL(上) <第三篇>

    说在,开篇之前 很早就有说说Metadata(元数据)和IL(中间语言)的想法了,一直在这篇开始才算脚踏实地的对这两个阶级兄弟投去些细关怀,虽然来得没有<第一回:恩怨情仇:is和as>那么 ...

  4. C# Struct结构体

    C#中结构类型和类类型在语法上非常相似,他们都是一种数据结构,都可以包括数据成员和方法成员. 结构和类的区别: 1.结构是值类型,它在栈中分配空间:而类是引用类型,它在堆中分配空间,栈中保存的只是引用 ...

  5. UESTC_邱老师的脑残粉 2015 UESTC Training for Graph Theory<Problem D>

    D - 邱老师的脑残粉 Time Limit: 12000/4000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Sub ...

  6. ZOJ3578(Matrix)

    Matrix Time Limit: 10 Seconds      Memory Limit: 131072 KB A N*M coordinate plane ((0, 0)~(n, m)). I ...

  7. 删除一个表中的重复数据同时保留第一次插入那一条以及sql优化

    业务:一个表中有很多数据(id为自增主键),在这些数据中有个别数据出现了重复的数据. 目标:需要把这些重复数据删除同时保留第一次插入的那一条数据,还要保持其它的数据不受影响. 解题过程: 第一步:查出 ...

  8. cocos2d-x绑定ccb文件

    首先,ccb文件是如何生成的,我就不多说了,大家可以搜下cocosbuilder,就能找的相关的教程,而通过cocosbuilder,我们可以省去了很多设计的麻烦,比如设计一个精灵的位置啥的,而通过c ...

  9. nginx默认虚拟主机

    server { listen 80 default_server; server_name localhost; index index.html index.htm index.php; root ...

  10. Java - 反射机制(Reflection)

    Java - 反射机制(Reflection)     > Reflection 是被视为 动态语言的关键,反射机制允许程序在执行期借助于 Reflection API 取得任何类的       ...