zoukankan      html  css  js  c++  java
  • QT:浮动的饼状统计图(自绘不规则窗口)

        昨天在玩手机游戏时,见到一个游戏的饼状投票统计图很漂亮,所以我今天也花了一个下午来实现了一个类似的程序娱乐一下,呵呵。

    思路:
    1:将窗体设为Qt::FramelessWindowHint和Qt::WA_TranslucentBackground(去掉标题栏,背景透明)。
    2:重载程序的鼠标事件(移动程序)和键盘事件(模拟投票和退出)。
    3:根据投票结果,在paintEvent函数中画几个扇形和其他东西。

    操作说明:
    1:按数字键0-9模拟投票。

    2:按ESC键退出程序。

    运行时截图(浅绿色的是桌面背景):

    源代码:

      1. #include <QtGui>  
      2.   
      3. class PieDialog : public QDialog  
      4. {  
      5.     Q_OBJECT  
      6. private:  
      7.     int m_Result[10];  
      8.     QColor m_Color[10];  
      9.     QPoint m_CurrentPos;  
      10. protected:      
      11.     void mousePressEvent(QMouseEvent *event);      
      12.     void mouseMoveEvent(QMouseEvent *event);      
      13.     void paintEvent(QPaintEvent *event);      
      14.     void enterEvent(QEvent *event);      
      15.     void leaveEvent(QEvent *event);   
      16.     void keyPressEvent(QKeyEvent *event);  
      17. public:  
      18.     PieDialog(QWidget *parent = 0);  
      19. };  
      20.   
      21. PieDialog::PieDialog(QWidget *parent /* = 0 */)  
      22. : QDialog(parent)  
      23. {  
      24.     m_Color[0] = Qt::red;  
      25.     m_Color[1] = Qt::green;  
      26.     m_Color[2] = Qt::blue;  
      27.     m_Color[3] = Qt::cyan;  
      28.     m_Color[4] = Qt::magenta;  
      29.     m_Color[5] = Qt::yellow;  
      30.     m_Color[6] = Qt::darkYellow;  
      31.     m_Color[7] = Qt::darkRed;  
      32.     m_Color[8] = Qt::darkGreen;  
      33.     m_Color[9] = Qt::darkCyan;  
      34.     qMemSet(m_Result, 0, sizeof(m_Result));  
      35.     setWindowTitle("Pie Dialog");  
      36.     setFixedSize(400, 300);  
      37.     //让程序背景透明  
      38.     setWindowFlags( Qt::FramelessWindowHint );  
      39.     setAttribute(Qt::WA_TranslucentBackground, true);  
      40. }  
      41.   
      42. void PieDialog::mousePressEvent(QMouseEvent *event)      
      43. {      
      44.     //按住左键可以托动窗口  
      45.     if(event->button() == Qt::LeftButton)      
      46.     {      
      47.         m_CurrentPos = event->globalPos() - frameGeometry().topLeft();      
      48.         event->accept();      
      49.     }      
      50.     QDialog::mousePressEvent(event);  
      51. }      
      52.   
      53. void PieDialog::mouseMoveEvent(QMouseEvent *event)      
      54. {      
      55.     if (event->buttons() && Qt::LeftButton)      
      56.     {      
      57.         move(event->globalPos() - m_CurrentPos);      
      58.         event->accept();      
      59.     }      
      60.     QDialog::mouseMoveEvent(event);  
      61. }      
      62.   
      63. void PieDialog::keyPressEvent(QKeyEvent *event)  
      64. {  
      65.     //按数字键1-0相当于投票  
      66.     for(int i=0; i<10; i++)  
      67.     {  
      68.         if( Qt::Key_0+i == event->key() )  
      69.         {  
      70.             m_Result[i]++;  
      71.             break;  
      72.         }  
      73.     }  
      74.     update();  
      75.     QDialog::keyPressEvent(event);  
      76. }  
      77.   
      78.   
      79. void PieDialog::paintEvent(QPaintEvent *event)      
      80. {     
      81.     QPainter painter(this);  
      82.     //反走样  
      83.     painter.setRenderHint(QPainter::Antialiasing, true);  
      84.     int cy = 10;  
      85.     //先画出颜色图解  
      86.     for(int i=0; i<10; i++)  
      87.     {  
      88.         painter.setBrush( m_Color[i] );  
      89.         painter.drawRect(320, cy, 30, 20);  
      90.         painter.drawText( QPoint(360, cy+15), QString::number(i) );   
      91.         cy += 28;  
      92.     }  
      93.     painter.setPen( QPen(Qt::black, 1) );  
      94.     const int FULL_CIRCLE = 5760;  
      95.     const int RADIUS = 140;  
      96.     QRect rect(10, 10, 280, 280);  
      97.     int count = 0;  
      98.     for(int i=0; i<10; i++)  
      99.     {  
      100.         count += m_Result[i];  
      101.     }  
      102.     //如果还没有投过票,那就先画一个白色的圆形  
      103.     if( 0 == count )  
      104.     {  
      105.         painter.setBrush( Qt::white );  
      106.         painter.drawEllipse(rect);  
      107.         return;  
      108.     }  
      109.   
      110.     int pos = 0;  
      111.     int angle;  
      112.     for(int i=0; i<10; i++)  
      113.     {  
      114.         if( 0 == m_Result[i] )  
      115.             continue;  
      116.         painter.setBrush( m_Color[i] );  
      117.         double persent = (double)m_Result[i] / count;  
      118.         angle = FULL_CIRCLE * persent;  
      119.   
      120.         //画出各个对应的扇形  
      121.         double abc = 3.14 * 2 * (double)(pos + angle/2) / FULL_CIRCLE;   
      122.         double tx = 100 * qCos(abc) + 10 + RADIUS;  
      123.         double ty = -100 * qSin(abc) + 10 + RADIUS;  
      124.         painter.drawPie(rect, pos, angle);  
      125.         //在扇形上写注释(投票数和百分比)  
      126.         QString temp;  
      127.         temp.sprintf(" (%d) ", m_Result[i]);  
      128.         painter.drawText(tx-20, ty-10, temp);  
      129.         temp.sprintf("%0.1lf%%", persent*100);  
      130.         painter.drawText(tx-20, ty, temp);  
      131.         pos += angle;  
      132.     }  
      133.      
      134. }      
      135.   
      136. void PieDialog::leaveEvent(QEvent *event)      
      137. {      
      138.     //鼠标离开窗口时是普通的指针      
      139.     setCursor(Qt::ArrowCursor);      
      140. }      
      141.   
      142. void PieDialog::enterEvent(QEvent *event)      
      143. {      
      144.     //鼠标留在窗口上时是一个手指      
      145.     setCursor(Qt::PointingHandCursor);      
      146. }      
      147.   
      148. #include "main.moc"      
      149.   
      150. int main(int argc, char *argv[])      
      151. {      
      152.     QApplication app(argc, argv);      
      153.     PieDialog *dialog = new PieDialog;      
      154.     dialog->show();      
      155.     return app.exec();      
      156. }      

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

  • 相关阅读:
    PowerDesigner概念设计模型(CDM)中的3种实体关系
    基于Prototype 1.6.2 框架下的数据分页
    中国地区,北京54坐标系条带号的选
    C#中MessageBox的使用
    C#注册表的读,写,删除,查找 (转)
    C# Tostring() 格式大全 [转]
    Layer features in this layer set, ArcEngine图层标注源码 (转)
    判断点是否在多边形之内的方法
    C#导入Excel到Dataset和导出Excel到DataTable
    Server.MapPath方法的应用方法
  • 原文地址:https://www.cnblogs.com/findumars/p/4993540.html
Copyright © 2011-2022 走看看