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



源代码:
- #include <QtGui>
- //状态类的基类,定义了各个公用接口,
- //其中,SetPixmap是一个纯虚接口
- class BasePen
- {
- protected:
- //这三个类成员理应是BasePen的私有成员,然后通过接口访问
- //我这里为了方便,直接把它们设为保护成员了
- QPixmap m_Pixmap;
- QPoint m_StartPoint;
- QPoint m_EndPoint;
- virtual void SetPixmap() = 0;
- public:
- BasePen()
- {
- m_StartPoint = m_EndPoint = QPoint(0, 0);
- m_Pixmap = QPixmap(500, 500);
- }
- void SetStartPoint(QPoint point) { m_StartPoint = point; }
- void SetEndPoint(QPoint point)
- {
- m_EndPoint = point;
- SetPixmap();
- }
- QPixmap GetPixmap() { return m_Pixmap; }
- };
- //矩形类,在界面上画一个红色的矩形
- class RectPen : public BasePen
- {
- protected:
- void SetPixmap()
- {
- m_Pixmap.fill(Qt::white);
- QPainter painter(&m_Pixmap);
- QRect rect(m_StartPoint, m_EndPoint);
- painter.setPen(Qt::red);
- painter.drawRect(rect);
- }
- };
- //直线类,在界面上画一条蓝色的直线
- class LinePen : public BasePen
- {
- protected:
- void SetPixmap()
- {
- m_Pixmap.fill(Qt::white);
- QPainter painter(&m_Pixmap);
- painter.setPen(Qt::blue);
- painter.drawLine(m_StartPoint, m_EndPoint);
- }
- };
- //圆形类,在界面上画一个绿色的椭圆
- class CirclePen : public BasePen
- {
- protected:
- void SetPixmap()
- {
- m_Pixmap.fill(Qt::white);
- QPainter painter(&m_Pixmap);
- QRect rect(m_StartPoint, m_EndPoint);
- painter.setPen(Qt::green);
- painter.drawEllipse(rect);
- }
- };
- class Widget : public QWidget
- {
- Q_OBJECT
- private:
- bool m_MouseDown;
- BasePen *m_BasePen;
- RectPen *m_RectPen;
- LinePen *m_LinePen;
- CirclePen *m_CirclePen;
- //在界面上放三个按钮,用来控制画图状态
- QRadioButton *m_LineButton;
- QRadioButton *m_RectButton;
- QRadioButton *m_CircleButton;
- protected:
- void mousePressEvent(QMouseEvent *event);
- void mouseMoveEvent(QMouseEvent *event);
- void mouseReleaseEvent(QMouseEvent *event);
- void paintEvent(QPaintEvent *event);
- public:
- Widget(QWidget *parent = 0);
- ~Widget();
- private slots:
- void ClickedLineButton() { m_BasePen = m_LinePen; }
- void ClickedRectButton() { m_BasePen = m_RectPen; }
- void ClickedCircleButton() { m_BasePen = m_CirclePen; }
- };
- Widget::Widget(QWidget *parent /* = 0 */)
- : QWidget(parent)
- {
- m_MouseDown = false;
- m_RectPen = new RectPen;
- m_LinePen = new LinePen;
- m_CirclePen = new CirclePen;
- m_LineButton = new QRadioButton("Line", this);
- m_RectButton = new QRadioButton("Rect", this);
- m_CircleButton = new QRadioButton("Circle", this);
- m_LineButton->move(10, 10);
- m_RectButton->move(100, 10);
- m_CircleButton->move(200, 10);
- connect(m_LineButton, SIGNAL(clicked()), this, SLOT(ClickedLineButton()));
- connect(m_RectButton, SIGNAL(clicked()), this, SLOT(ClickedRectButton()));
- connect(m_CircleButton, SIGNAL(clicked()), this, SLOT(ClickedCircleButton()));
- m_BasePen = m_LinePen;
- m_LineButton->setChecked(true);
- setFixedSize(500, 500);
- }
- Widget::~Widget()
- {
- delete m_LinePen;
- delete m_RectPen;
- delete m_CirclePen;
- }
- void Widget::mousePressEvent(QMouseEvent *event)
- {
- if( event->button() == Qt::LeftButton )
- {
- m_MouseDown = true;
- m_BasePen->SetStartPoint(event->pos());
- }
- }
- void Widget::mouseMoveEvent(QMouseEvent *event)
- {
- if( m_MouseDown )
- {
- m_BasePen->SetEndPoint(event->pos());
- update();
- }
- }
- void Widget::mouseReleaseEvent(QMouseEvent *event)
- {
- if( event->button() == Qt::LeftButton )
- {
- m_MouseDown = false;
- }
- }
- void Widget::paintEvent(QPaintEvent *event)
- {
- QPixmap temp = m_BasePen->GetPixmap();
- QPainter painter(this);
- painter.drawPixmap(0, 0, temp);
- }
- #include "main.moc"
- int main(int argc, char **argv)
- {
- QApplication app(argc, argv);
- Widget *ww = new Widget;
- ww->show();
- return app.exec();
- }
http://blog.csdn.net/small_qch/article/details/7632226
QT:使用“状态模式”绘制界面的更多相关文章
- Android自定义控件7--自定义开关--绘制界面内容
本文实现全自定义控件--自定义开关 本文地址:http://www.cnblogs.com/wuyudong/p/5922316.html,转载请注明源地址. 自定义开关 (View),本文完成下面内 ...
- iOS - 在工程中试玩状态模式
做了一个项目,项目中一个藏品详情界面针对不同用户,和用户所处于的状态的不同,展示的效果和操作的权限都会不同.想到了状态模式,从来没有用过,赶紧学一下然后用一用.期待兴奋 看了这么多的博客,终于找到一个 ...
- 【状态模式】 State Pattern
我们先设计一个场景,饮料自动售卖机,来设计一下它的出售流程. 流程图中,我们可把这个过程看成几个状态: 投币状态,选择饮料状态,售出状态,出售完毕状态. ,有了这个四个状态,我们设计一下界面(很粗略) ...
- 【转】设计模式 ( 十七) 状态模式State(对象行为型)
设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...
- (转)Qt Model/View 学习笔记 (一)——Qt Model/View模式简介
Qt Model/View模式简介 Qt 4推出了一组新的item view类,它们使用model/view结构来管理数据与表示层的关系.这种结构带来的 功能上的分离给了开发人员更大的弹性来定制数据项 ...
- 设计模式 ( 十八 ):State状态模式 -- 行为型
1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ellse语句来做状态判断来进行不同情况的处理.但是对 ...
- 设计模式 ( 十七) 状态模式State(对象行为型)
设计模式 ( 十七) 状态模式State(对象行为型) 1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ...
- JavaScript中的设计模式:状态模式
前几天写了一个贪吃蛇小游戏,正好用到了状态模式. 定义 当一个对象内部状态发生改变时候,会导致其行为的改变,这看起来像是改变了对象. 简单的例子 如果一个函数要更具某一个对象的状态来判断该对象应该执行 ...
- Java设计模式(19)状态模式(State模式)
State的定义:不同的状态,不同的行为:或者说,每个状态有着相应的行为. 何时使用状态模式 State模式在实际使用中比较多,适合"状态的切换".因为我们经常会使用If else ...
随机推荐
- 垃圾回收GC——JVM之七
垃圾回收是个复杂的过程: 请以此阅读下列文章: 垃圾回收1:http://blog.csdn.net/sun305355024sun/article/details/41394729 垃圾回收2:ht ...
- Oracle Trunc
http://www.cnblogs.com/xiaoyudz/archive/2011/03/18/1988467.html
- [置顶] SPL讲解(7)--Query高级篇
SmartPersistenceLayer 2.0 之Query高级查询篇 总述 在看了前面的功能后,大家都会考虑到多表之间的查询怎么办.在这里,我想先讲一下查询在应用系统中的复杂性/重要性/可行性. ...
- zabbix 通过gateway 获取远程主机的JMX信息
DBHost=192.168.32.55 DBName= zabbix DBUser=zabbixuser DBPassword=zabbixpass StartTrappers=20 MaxHous ...
- httrack,webdup,WinHTTrack,WebZip
怎么下载摄像头游戏jabbo,并使其能离线运行?修改 1.摄像头游戏jabbo:JABBO Ultimatum by LiveMurals Interactive电脑为:windows 7 32位.试 ...
- qsort排序算法
七种qsort排序方法 <本文中排序都是采用的从小到大排序> 一.对int类型数组排序 int num[100]; Sample: int cmp ( const void *a , ...
- 关于随机数字K线极值的统计结果
如果有组随机数字,如数字彩票.我们对号码进行平均二分后,统计期出现的结果分布,对结果分布进行K线累加,得到一条折线. 这条折线的顶点和底点的统计上服从以下规则: 令总期数为N,统计区间为M,则在N期内 ...
- Zookeeper 1、Zookeeper 定义与工作原理
1.什么是Zookeeper » Zookeeper 是 Google 的 Chubby一个开源的实现,是 Hadoop 的分布式协调服务 » 它包含一个简单的原语集,分布式应用程序可以基于它实现同步 ...
- PHP MySQL Order By 关键词 之 Order By
ORDER BY 关键词 ORDER BY 关键词用于对记录集中的数据进行排序. 语法 SELECT column_name(s) FROM table_name ORDER BY column_na ...
- 编程获取linux的CPU使用的内存使用情况
Linux可用下top.ps命令检查当前的cpu.mem用法.下面简单的例子: 一.采用ps查看资源消耗的过程 ps -aux 当您查看进程信息,第三列是CPU入住. [root@localhost ...