QT:浮动的饼状统计图(自绘不规则窗口)

本文介绍了一款使用Qt库实现的投票统计饼图小程序,通过简单的键盘输入即可进行投票,并实时显示投票结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

2:按ESC键退出程序。


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



源代码:

[cpp] view plaincopyprint?

    #include <QtGui>  
      
    class PieDialog : public QDialog  
    {  
        Q_OBJECT  
    private:  
        int m_Result[10];  
        QColor m_Color[10];  
        QPoint m_CurrentPos;  
    protected:      
        void mousePressEvent(QMouseEvent *event);      
        void mouseMoveEvent(QMouseEvent *event);      
        void paintEvent(QPaintEvent *event);      
        void enterEvent(QEvent *event);      
        void leaveEvent(QEvent *event);   
        void keyPressEvent(QKeyEvent *event);  
    public:  
        PieDialog(QWidget *parent = 0);  
    };  
      
    PieDialog::PieDialog(QWidget *parent /* = 0 */)  
    : QDialog(parent)  
    {  
        m_Color[0] = Qt::red;  
        m_Color[1] = Qt::green;  
        m_Color[2] = Qt::blue;  
        m_Color[3] = Qt::cyan;  
        m_Color[4] = Qt::magenta;  
        m_Color[5] = Qt::yellow;  
        m_Color[6] = Qt::darkYellow;  
        m_Color[7] = Qt::darkRed;  
        m_Color[8] = Qt::darkGreen;  
        m_Color[9] = Qt::darkCyan;  
        qMemSet(m_Result, 0, sizeof(m_Result));  
        setWindowTitle("Pie Dialog");  
        setFixedSize(400, 300);  
        //让程序背景透明  
        setWindowFlags( Qt::FramelessWindowHint );  
        setAttribute(Qt::WA_TranslucentBackground, true);  
    }  
      
    void PieDialog::mousePressEvent(QMouseEvent *event)      
    {      
        //按住左键可以托动窗口  
        if(event->button() == Qt::LeftButton)      
        {      
            m_CurrentPos = event->globalPos() - frameGeometry().topLeft();      
            event->accept();      
        }      
        QDialog::mousePressEvent(event);  
    }      
      
    void PieDialog::mouseMoveEvent(QMouseEvent *event)      
    {      
        if (event->buttons() && Qt::LeftButton)      
        {      
            move(event->globalPos() - m_CurrentPos);      
            event->accept();      
        }      
        QDialog::mouseMoveEvent(event);  
    }      
      
    void PieDialog::keyPressEvent(QKeyEvent *event)  
    {  
        //按数字键1-0相当于投票  
        for(int i=0; i<10; i++)  
        {  
            if( Qt::Key_0+i == event->key() )  
            {  
                m_Result[i]++;  
                break;  
            }  
        }  
        update();  
        QDialog::keyPressEvent(event);  
    }  
      
      
    void PieDialog::paintEvent(QPaintEvent *event)      
    {     
        QPainter painter(this);  
        //反走样  
        painter.setRenderHint(QPainter::Antialiasing, true);  
        int cy = 10;  
        //先画出颜色图解  
        for(int i=0; i<10; i++)  
        {  
            painter.setBrush( m_Color[i] );  
            painter.drawRect(320, cy, 30, 20);  
            painter.drawText( QPoint(360, cy+15), QString::number(i) );   
            cy += 28;  
        }  
        painter.setPen( QPen(Qt::black, 1) );  
        const int FULL_CIRCLE = 5760;  
        const int RADIUS = 140;  
        QRect rect(10, 10, 280, 280);  
        int count = 0;  
        for(int i=0; i<10; i++)  
        {  
            count += m_Result[i];  
        }  
        //如果还没有投过票,那就先画一个白色的圆形  
        if( 0 == count )  
        {  
            painter.setBrush( Qt::white );  
            painter.drawEllipse(rect);  
            return;  
        }  
      
        int pos = 0;  
        int angle;  
        for(int i=0; i<10; i++)  
        {  
            if( 0 == m_Result[i] )  
                continue;  
            painter.setBrush( m_Color[i] );  
            double persent = (double)m_Result[i] / count;  
            angle = FULL_CIRCLE * persent;  
      
            //画出各个对应的扇形  
            double abc = 3.14 * 2 * (double)(pos + angle/2) / FULL_CIRCLE;   
            double tx = 100 * qCos(abc) + 10 + RADIUS;  
            double ty = -100 * qSin(abc) + 10 + RADIUS;  
            painter.drawPie(rect, pos, angle);  
            //在扇形上写注释(投票数和百分比)  
            QString temp;  
            temp.sprintf(" (%d) ", m_Result[i]);  
            painter.drawText(tx-20, ty-10, temp);  
            temp.sprintf("%0.1lf%%", persent*100);  
            painter.drawText(tx-20, ty, temp);  
            pos += angle;  
        }  
         
    }      
      
    void PieDialog::leaveEvent(QEvent *event)      
    {      
        //鼠标离开窗口时是普通的指针      
        setCursor(Qt::ArrowCursor);      
    }      
      
    void PieDialog::enterEvent(QEvent *event)      
    {      
        //鼠标留在窗口上时是一个手指      
        setCursor(Qt::PointingHandCursor);      
    }      
      
    #include "main.moc"      
      
    int main(int argc, char *argv[])      
    {      
        QApplication app(argc, argv);      
        PieDialog *dialog = new PieDialog;      
        dialog->show();      
        return app.exec();      
    }      

http://blog.youkuaiyun.com/aaa20090987/article/details/7607491
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值