Qt5 双滑块支持float变化的控件,以及单滑块float控件,供大家参考

最近做到一个项目,需要设置一个参数的上下限,最开始考虑的办法是用QSlider控件来实现,发现有两个不太合适的地方。
  • 一个参数需要用两个控件来设置,而且两者之间还有大小关系的限制,比较麻烦;
  • QSlider只支持int类型的输入与改变。
因此,决定自己写一个,本着资源共享的精神,特将代码贴出,供大家参考,如有更好的想法,也欢迎指正与交流。

双滑块的代码

#ifndef DOUBLESLIDER_H
#define DOUBLESLIDER_H

#include 
    
    
     
     

class DoubleSlider : public QWidget
{
    Q_OBJECT
public:
    DoubleSlider(QWidget* parent = 0);
    void setRange(float min, float max);
    void setSingleStep(float step);

    enum State{ MinHandle,MaxHandle,None};

    float minValue() const;
    float maxValue() const;

    float minRange() const;
    float maxRange() const;

public slots:
    void setLabel(const QString& label);
    void setMaxValue(float val);
    void setMinValue(float val);

signals:
    void minValueChanged(float);
    void maxValueChanged(float);

private:
    float m_min;
    float m_max;
    float m_singleStep;

    float m_minValue;
    float m_maxValue;

    QRect minHandleRegion;
    QRect maxHandleRegion;

    State m_state;

    QString m_label;

protected:
    void paintEvent(QPaintEvent* event);
    void paintColoredRect(QRect rect, QColor color, QPainter* painter);
    void paintValueLabel(QPainter* painter);

    void mousePressEvent(QMouseEvent* event);
    void mouseMoveEvent(QMouseEvent* event);

    void keyPressEvent(QKeyEvent *event);
    void leaveEvent(QEvent* event);

};

#endif // DOUBLESLIDER_H
#include "doubleslider.h"
#include 
     
     
      
      
#include 
      
      
       
       

DoubleSlider::DoubleSlider(QWidget* parent)
    : QWidget(parent)
    , m_min(0.0f)
    , m_max(99.0f)
    , m_singleStep(0.1f)
    , m_minValue(0.0f)
    , m_maxValue(99.0f)
    , m_state(None)
{
    setFixedHeight(50);
    setFocusPolicy(Qt::StrongFocus);
}

void DoubleSlider::paintEvent(QPaintEvent* event)
{
    QWidget::paintEvent(event);
    QPainter painter(this);
    paintValueLabel(&painter);
}

void DoubleSlider::paintColoredRect(QRect rect, QColor color ,QPainter* painter)
{
    painter->fillRect(rect,QBrush(color));
}

void DoubleSlider::paintValueLabel(QPainter* painter)
{
    painter->setBrush(Qt::NoBrush);
    painter->setPen(Qt::black);
    painter->setFont(QFont("Arial",12));

    QString minValueString = QString::number(m_minValue,'f',3);
    QString maxValueString = QString::number(m_maxValue,'f',3);

    QFontMetrics metrics = painter->fontMetrics();
    int mintextWidth = metrics.width(minValueString);
    int maxtextWidth = metrics.width(maxValueString);
    int textHeight = metrics.height();

    //---- paint text
    painter->drawText(QRectF(2,4,mintextWidth,textHeight),minValueString);
    painter->drawText(QRectF(width() - maxtextWidth -2, 4, maxtextWidth,textHeight), maxValueString);


    //----- paint label
    painter->setFont(QFont("Arial",12));
    metrics = painter->fontMetrics();
    int labelWidth = metrics.width(m_label);
    int labelHeight = metrics.height();

    QRectF textRect = QRectF((width()/2 - labelWidth/2), 0,labelWidth,labelHeight);

    painter->drawText(textRect,m_label);


    int minPos = ( m_minValue - m_min ) * width() / (m_max - m_min);
    int maxPos = (m_maxValue - m_min ) * width() /  (m_max - m_min);

    if(minPos <= 4){
        minPos = 4;
    }else if(minPos >= width() - 8){
        minPos = width() - 8;
    }else{}

    if(maxPos <= 4){
        maxPos = 4;
    }else if(maxPos >= width() -8){
        maxPos = width() - 8;
    }else{}


    //----- paint groove
    paintColoredRect(QRect(4,37,width() - 8,2),Qt::gray,painter);
    paintColoredRect(QRect(minPos + 4,37,maxPos - minPos,2),QColor(51,153,155),painter);

    //----- handle

    minHandleRegion = QRect(minPos ,30,8,16);
    maxHandleRegion = QRect(maxPos ,30,8,16);

    //-----paint Handle
    QColor minColor  = (m_state == MinHandle) ? QColor(51,153,155) : Qt::darkGray;
    QColor maxColor  = (m_state == MaxHandle) ? QColor(51,153,155) : Qt::darkGray;
    paintColoredRect(minHandleRegion,minColor,painter);
    paintColoredRect(maxHandleRegion,maxColor,painter);
}

inline float getValidValue(float val, float min, float max)
{
    float tmp = std::max(val, min);
    return std::min(tmp, max);
}


void DoubleSlider::setRange(float min, float max)
{
    m_min = min;
    m_max = max;

    if(minValue() < m_min)
        setMinValue(m_min);

    if(maxValue() > m_max){
        setMaxValue(m_max);
    }
}

void DoubleSlider::setSingleStep(float step)
{
    m_singleStep = step;
}

float DoubleSlider::minValue() const
{
    return m_minValue;
}
void DoubleSlider::setMinValue(float val)
{
    if(fabs( m_minValue - val ) > 0.0001 ){
        m_minValue = val;
        emit minValueChanged(val);
    }
}

float DoubleSlider::maxValue() const
{
    return m_maxValue;
}
void DoubleSlider::setMaxValue(float val)
{
    if(fabs(m_maxValue - val) > 0.0001){
        m_maxValue = val;
        emit maxValueChanged(val);
    }
}

void DoubleSlider::setLabel(const QString& label)
{
   m_label = label;
   update();
}

void DoubleSlider::leaveEvent(QEvent* event)
{
    QWidget::leaveEvent(event);
    m_state = None;
    update();
}

float DoubleSlider::minRange() const
{
    return m_min;
}
float DoubleSlider::maxRange() const
{
    return m_max;
}


void DoubleSlider::mousePressEvent(QMouseEvent* event)
{
    if(minHandleRegion.contains(event->pos())){
        m_state = MinHandle;
    }else if(maxHandleRegion.contains(event->pos())){
        m_state = MaxHandle;
    }else{
        m_state = None;
    }

    if(fabs(minValue() - maxValue()) < 0.001){
        if(fabs(minValue() - m_min) < 0.001){
            m_state = MaxHandle;
        }else if(fabs(minValue() - m_max) < 0.001){
            m_state = MinHandle;
        }else{}
    }

    update();
}

void DoubleSlider::mouseMoveEvent(QMouseEvent* event)
{
    if(event->buttons() & Qt::LeftButton){
        float move = event->x() * (m_max - m_min) * 1.0/ width() + m_min;

        switch(m_state){
            case MinHandle:{
                float val = getValidValue( move, m_min,maxValue());
                setMinValue(val);
                break;
            }

            case MaxHandle:{
                    float val = getValidValue(move, minValue(), m_max);
                    setMaxValue(val);
                    break;
            }
            case None:default: break;
        }
    }
    update();
}


void DoubleSlider::keyPressEvent(QKeyEvent *event)
{
    QWidget::keyPressEvent(event);

    if(event->key() == Qt::Key_Left){
        if(m_state == MinHandle){
            float val = getValidValue(minValue()- m_singleStep, m_min ,maxValue());
            setMinValue(val);
        }else if(m_state == MaxHandle) {
            float val = getValidValue(maxValue()- m_singleStep, minValue() ,m_max);
            setMaxValue(val);
        }else{}
    }else if(event->key() == Qt::Key_Right){
        if(m_state == MinHandle){
            float val = getValidValue(minValue() + m_singleStep, m_min ,maxValue());
            setMinValue(val);
        }else if(m_state == MaxHandle) {
            float val = getValidValue(maxValue() + m_singleStep, minValue() ,m_max);
            setMaxValue(val);
        }else{}
    }

    update();

}



      
      
     
     
    
    




好的,针对您的问题,我可以详细介绍一下如何使用QT编程工具来编写带界面的仿真控制程序,实现灯光自动调节功能。 1. 创建QT项目 首先,打开QT Creator工具,选择"File" -> "New File or Project",在弹出的对话框中选择"Qt Widgets Application",然后点击"Choose"按钮,输入项目名称、项目路径等信息,最后点击"Next"按钮。 2. 添加滑块控件 接下来,我们需要在程序界面上添加一个滑块控件,用于模拟灯光数值的变化。在QT Creator的窗口中,选择"Design"模式,在左侧控件列表中找到"Slider"控件,将其拖拽到程序界面上。 然后,右键点击"Slider"控件,选择"Change Object Name",将其命名为"brightness_slider"。接着,我们需要设置滑块控件的数值范围、精度等属性。在QT Creator的属性编辑器中,找到"Range"属性,将其设置为"0-100",然后找到"Tick Interval"属性,将其设置为"10"。 3. 实现灯光自动调节功能 现在,我们已经完成了滑块控件的添加和设置。接下来,我们需要实现灯光自动调节功能。具体来说,我们需要实现以下几个步骤: - 监测环境光线强度。使用QT的定时器和串口通信功能,在程序中定时读取光敏电阻或光电二极管等传感器的数值,并将其转换为环境光线强度。 - 计算灯光亮度。根据环境光线强度计算灯光亮度,并将计算结果设置为滑块控件的数值。 - 自动调节灯光亮度。通过QT的信号槽机制,将滑块控件的数值与实际的灯光亮度相连接,实现灯光的自动调节。 以下是具体的实现步骤: - 在程序的头文件中添加以下代码: ``` #include <QTimer> #include <QSerialPort> ``` - 在程序的主窗口类中定义以下变量: ``` private: QTimer *timer; QSerialPort *serial; float light_intensity; ``` - 在程序的构造函数中初始化定时器和串口: ``` MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { ui.setupUi(this); timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(readLightIntensity())); serial = new QSerialPort(this); serial->setPortName("/dev/ttyUSB0"); // 设置串口号 serial->setBaudRate(QSerialPort::Baud9600); // 设置波特率 serial->open(QIODevice::ReadWrite); // 打开串口 light_intensity = 0.0; } ``` - 实现监测环境光线强度的函数readLightIntensity(): ``` void MainWindow::readLightIntensity() { serial->write("R"); // 发送读取光线强度的指令 serial->waitForReadyRead(); QByteArray data = serial->readAll(); float raw_value = data.toFloat(); light_intensity = raw_value / 1023 * 5; // 将ADC数值转换为电压值 } ``` - 实现计算灯光亮度的函数calculateBrightness(): ``` void MainWindow::calculateBrightness() { float brightness = light_intensity * 20; // 根据电压值计算亮度值 ui.brightness_slider->setValue(brightness); // 设置滑块控件的数值 } ``` - 在程序的开始按钮槽函数中启动定时器: ``` void MainWindow::on_start_button_clicked() { timer->start(1000); // 每秒读取一次光线强度 connect(ui.brightness_slider, SIGNAL(valueChanged(int)), this, SLOT(setBrightness(int))); } ``` - 实现自动调节灯光亮度的函数setBrightness(): ``` void MainWindow::setBrightness(int value) { // 设置灯光亮度为滑块控件的数值 // 可以根据具体的需求使用PWM控制灯光的亮度 } ``` 这样,我们就完成了灯光自动调节功能的实现。当用户点击程序界面上的"开始"按钮后,程序会定时读取光敏电阻或光电二极管等传感器的数值,并根据环境光线强度计算灯光亮度。然后,程序会将计算结果设置为滑块控件的数值,实现灯光的自动调节。 需要注意的是,以上代码仅是一个简的示例,具体实现还需要根据具体的需求进行设计和编码。另外,QT了丰富的控件和功能,可以帮助我们轻松地实现各种功能。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值