QT与很多GUI库不同(如MFC),它不能随时随地地在界面上画图,只能在界面类的painterEvent中画图,如此一来,想在绘制QT界面时使用状态模式(GOF的23种设计模式之一)就有点困难了,作为解决方案,我先把要界面上的图片绘制在一张图片上(QPixmap),然后再在painterEvent中将Pixmap“画”到界面上。以下是这种方法的一个小例子。
截图:
源代码:
main.cpp
1 2 3 4 5 6 7 8 9 10 11 |
#include "widget.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.show(); return a.exec(); } |
widget.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QRadioButton> #include "basepen.h" #include "rectpen.h" #include "linepen.h" #include "circlepen.h" 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; } }; #endif // WIDGET_H |
widget.cpp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
#include "widget.h" #include <QMouseEvent> 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); } |
basepen.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#ifndef BASEPEN #define BASEPEN //状态类的基类,定义了各个公用接口, //其中,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; } }; #endif // BASEPEN |
circlepen.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#ifndef CIRCLEPEN_H #define CIRCLEPEN_H #include "basepen.h" //圆形类,在界面上画一个绿色的椭圆 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); } }; #endif // CIRCLEPEN_H |
linepen.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
#ifndef LINEPEN #define LINEPEN #include "basepen.h" //直线类,在界面上画一条蓝色的直线 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); } }; #endif // LINEPEN |
rectpen.h
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#ifndef RECTPEN #define RECTPEN #include "basepen.h" #include <QPainter> //矩形类,在界面上画一个红色的矩形 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); } }; #endif // RECTPEN |
发表评论
要发表评论,您必须先登录。