今宵梦醒何去 2023-01-16 16:10 采纳率: 0%
浏览 68
已结题

求帮助,Qt项目控件样式实现!

Qt项目 window11 qt5.14
项目要求,需要制作一些控件,但是控件样式的实现有些困难

用Qt实现一些控件的样式,样式是美工提供的,需要实现美工提供的样式,而且控件可以缩放的

我试过border渐变和QGraphicsDropShadowEffect了,有效果,但是都不满意。

求帮助,有哪位老手可以分享一下想法,万分感谢!

下面是其中的两个控件的样式截图:

img


----------------------------------------分割线-------------------------------------

img

  • 写回答

5条回答 默认 最新

  • ilmss 2023-01-16 19:49
    关注

    你可以参考下实现方式:

    #ifndef MYDIAL_H
    #define MYDIAL_H
     
    #include <QWidget>
     
    class MyDial : public QWidget
    {
        Q_OBJECT
     
    public:
        MyDial(QWidget *parent = 0);
        ~MyDial();
     
        void setValue(double val);
     
    protected:
        void paintEvent(QPaintEvent *);
     
        void drawCrown(QPainter *painter);
        void drawBackground(QPainter *painter);
        void drawScale(QPainter *painter);
        void drawScaleNum(QPainter *painter);
        void drawTitle(QPainter *painter);
        void drawIndicator(QPainter *painter);
        void drawNumericValue(QPainter *painter);
     
    private:
        QColor m_background;
        QColor m_foreground;
     
     
        int m_maxValue;
        int m_minValue;
        int m_startAngle;
        int m_endAngle;
     
        int m_scaleMajor;
        int m_scaleMinor;
        double m_value;
        int m_precision;
        QTimer *m_updateTimer;
        QString m_units;
        QString m_title;
     
    public Q_SLOTS:
        void UpdateAngle();
     
    private:
     
    };
     
    #endif // MYDIAL_H
    
    #include "mydial.h"
     
    #include <QPainter>
     
    // 构造函数
    MyDial::MyDial(QWidget *parent){
        
        m_background = Qt::black;
        m_foreground = Qt::white;
     
        m_startAngle = 60;
        m_endAngle = 60;
        m_scaleMajor = 10;
        m_minValue = 0;
        m_maxValue = 100;
        m_scaleMajor = 10;//分度
        m_scaleMinor = 10;
        m_units = "L/min";
        m_title = "Water flow";
        m_precision = 0;
        m_value = 0;
     
        setWindowFlags(Qt::FramelessWindowHint);//无窗体
        setAttribute(Qt::WA_TranslucentBackground);//背景透明
        //resize(400, 400);
     
    }
     
    MyDial::~MyDial()
    {
     
    }
     
    void MyDial::setValue(double val)
    {
        m_value = val;
    }
    //绘制表冠 
    void MyDial::drawCrown(QPainter *painter)
    { 
        painter->save();
        int radius = 100;
        QLinearGradient lg1(0, -radius, 0, radius);
     
        lg1.setColorAt(0, Qt::white); //设置渐变的颜色和路径比例
        lg1.setColorAt(1, Qt::gray); //只是粗略的颜色,具体的可以参考RGB颜色查询对照表
     
        painter->setBrush(lg1); // 创建QBrush对象,把这个渐变对象传递进去:
        painter->setPen(Qt::NoPen); //边框线无色
        painter->drawEllipse(-radius, -radius, radius << 1, radius << 1);
        painter->setBrush(m_background = Qt::black);
        painter->drawEllipse(-92, -92, 184, 184);
        painter->restore();
    }
     
     //绘制刻度数字 
    void MyDial::drawScaleNum(QPainter *painter)
    { 
        painter->save();
        painter->setPen(m_foreground);
        //m_startAngle是起始角度,m_endAngle是结束角度,m_scaleMajor在一个量程中分成的刻度数
        double startRad = ( 270-m_startAngle) * (3.14 / 180);
        double deltaRad = (360 - m_startAngle - m_endAngle) * (3.14 / 180) / m_scaleMajor;
        double sina,cosa;
        int x, y;
        QFontMetricsF fm(this->font());
        double w, h, tmpVal;
        QString str;
     
        for (int i = 0; i <= m_scaleMajor; i++)
        {
            sina = sin(startRad - i * deltaRad);
            cosa = cos(startRad - i * deltaRad);
     
           tmpVal = 1.0 * i *((m_maxValue - m_minValue) / m_scaleMajor) + m_minValue;
           // tmpVal = 50;
            str = QString( "%1" ).arg(tmpVal);  //%1作为占位符   arg()函数比起 sprintf()来是类型安全的
            w = fm.size(Qt::TextSingleLine,str).width();
            h = fm.size(Qt::TextSingleLine,str).height();
            x = 82 * cosa - w / 2;
            y = -82 * sina + h / 4;
            painter->drawText(x, y, str); //函数的前两个参数是显示的坐标位置,后一个是显示的内容,是字符类型""
     
        }
        painter->restore();
    }
     
    // 绘制刻度线
    void MyDial::drawScale(QPainter *painter) //绘制刻度线
    { 
        painter->save();
        painter->rotate(m_startAngle);
        int steps = (m_scaleMajor * m_scaleMinor); //相乘后的值是分的份数
        double angleStep = (360.0 - m_startAngle - m_endAngle) / steps; //每一个份数的角度
     
        // painter->setPen(m_foreground); //m_foreground是颜色的设置
        // QPen pen = painter->pen(); //第一种方法
        QPen pen ;
        pen.setColor(Qt::green); //推荐使用第二种方式
        for (int i = 0; i <= steps; i++)
        {
        if (i % m_scaleMinor == 0)//整数刻度显示加粗
        {
        pen.setWidth(1); //设置线宽
        painter->setPen(pen); //使用面向对象的思想,把画笔关联上画家。通过画家画出来
     
          painter->drawLine(0, 62, 0, 72); //两个参数应该是两个坐标值
           }
           else
           {
               pen.setWidth(0);
               painter->setPen(pen);
               painter->drawLine(0, 67, 0, 72);
           }
           painter->rotate(angleStep);
        }
        painter->restore();
    }
     
    void MyDial::drawTitle(QPainter *painter)
    { 
        painter->save();
        painter->setPen(m_foreground);
        //painter->setBrush(m_foreground);
        QString str(m_title); //显示仪表的功能
        QFontMetricsF fm(this->font());
        double w = fm.size(Qt::TextSingleLine,str).width();
        painter->drawText(-w / 2, -30, str);
        painter->restore();
    }
     
    // 显示的单位,与数值
    void MyDial::drawNumericValue(QPainter *painter)
    { 
        QString str = QString("%1 %2").arg(m_value, 0, 'f', m_precision).arg(m_units);
        QFontMetricsF fm(font());
        double w = fm.size(Qt::TextSingleLine,str).width();
        painter->setPen(m_foreground);
        painter->drawText(-w / 2, 42, str);
    }
     
    void MyDial::UpdateAngle()
    {
        update();
    }
     
    // 绘制表针,和中心点
    void MyDial::drawIndicator(QPainter *painter)
    {
        painter->save();
        QPolygon pts;
        pts.setPoints(3, -2, 0, 2, 0, 0, 60);    /* (-2,0)/(2,0)/(0,60) *///第一个参数是 ,坐标的个数。后边的是坐标
     
        painter->rotate(m_startAngle);
        double degRotate = (360.0 - m_startAngle - m_endAngle) / (m_maxValue - m_minValue)*(m_value - m_minValue);
     
        //画指针
        painter->rotate(degRotate);  //顺时针旋转坐标系统
        QRadialGradient haloGradient(0, 0, 60, 0, 0);  //辐射渐变
        haloGradient.setColorAt(0, QColor(60, 60, 60));
        haloGradient.setColorAt(1, QColor(160, 160, 160)); //灰
        painter->setPen(Qt::white); //定义线条文本颜色  设置线条的颜色
        painter->setBrush(haloGradient);//刷子定义形状如何填满 填充后的颜色
        painter->drawConvexPolygon(pts); //这是个重载函数,绘制多边形。
        painter->restore();
     
        //画中心点
        QColor niceBlue(150, 150, 200);
        QConicalGradient coneGradient(0, 0, -90.0);  //角度渐变
        coneGradient.setColorAt(0.0, Qt::darkGray);
        coneGradient.setColorAt(0.2, niceBlue);
        coneGradient.setColorAt(0.5, Qt::white);
        coneGradient.setColorAt(1.0, Qt::darkGray);
        painter->setPen(Qt::NoPen);  //没有线,填满没有边界
        painter->setBrush(coneGradient);
        painter->drawEllipse(-5, -5, 10, 10);
    }
     
    // 重绘函数
    void MyDial ::paintEvent(QPaintEvent *)
    { 
     
        int width=this->width();
        int height=this->height();
     
        QPainter painter(this);//一个类中的this表示一个指向该类自己的指针
     
        painter.setRenderHint(QPainter::Antialiasing);  /* 使用反锯齿(如果可用) */
        painter.translate(width/2, height/2);   /* 坐标变换为窗体中心 */
        int side = qMin(width, height);
        painter.scale(side / 200.0, side / 200.0);      /* 比例缩放 */
     
       drawCrown(&painter);                                 /* 画表盘边框 */
       drawScaleNum(&painter);                          /* 画刻度数值值 */
       drawScale(&painter);                                 /* 画刻度线 */
       drawTitle(&painter);                                 /* 画单位 */
       drawNumericValue(&painter);                      /* 画数字显示 */
       drawIndicator(&painter);                             /* 画表针 */
     
    }
    
    
    评论

报告相同问题?

问题事件

  • 系统已结题 1月24日
  • 创建了问题 1月16日

悬赏问题

  • ¥15 自适应 AR 模型 参数估计Matlab程序
  • ¥100 角动量包络面如何用MATLAB绘制
  • ¥15 merge函数占用内存过大
  • ¥15 Revit2020下载问题
  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大
  • ¥15 单片机无法进入HAL_TIM_PWM_PulseFinishedCallback回调函数
  • ¥15 Oracle中如何从clob类型截取特定字符串后面的字符
  • ¥15 想通过pywinauto自动电机应用程序按钮,但是找不到应用程序按钮信息
  • ¥15 如何在炒股软件中,爬到我想看的日k线