zoukankan      html  css  js  c++  java
  • QT:使用“状态模式”绘制界面

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

    截图:

    源代码:

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

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

  • 相关阅读:
    Android三种菜单的使用方式
    Express无法解析POST请求的JSON参数
    reids数据备份与恢复
    docker获取数据库时间相差8小时
    centos添加新用户
    创建一个新的容器并运行一个命令
    docker启动容器时报错unknown shorthand flag: ‘n‘ in -name
    linux查看cpu详细信息
    ValueError: Shapes (None, 1) and (None, 2) are incompatible
    Python:IOError: image file is truncated 的解决办法
  • 原文地址:https://www.cnblogs.com/findumars/p/4993538.html
Copyright © 2011-2022 走看看