Qt5 解决QSlider的valueChanged槽函数中setValue导致一直回调的问题

Qt5 解决QSlider的valueChanged槽函数中setValue导致一直回调的问题

 

问题描述

       公司一款基于Qt开发的程序,想实现slider设置亮度失败后恢复之前的位置,设置亮度失败会弹窗提醒,结果出现了频繁点击一直弹窗的问题。用blockSignals、QTimer::singleshot、开线程对slider进行setValue都还是同样问题,翻了stackoverflow和Qt官方论坛,都只说到要用blockSignals,所以我只能认为是官方的bug了。

 

解决思路

1.用上面提到的 blockSignals、QTimer::singleshot、开线程,结果不行

2.开始怀疑是 valueChanged 的问题,换了 sliderReleased,各种暴力测试,没有发生槽函数一直响应的问题,但是鼠标点击slider最最右边的位置槽函数没回调,只能放弃 sliderReleased

3.重写QSlider中的 mouseReleaseEvent ,再测试结果可以了

 

上代码

#ifndef QHORSLIDER_H
#define QHORSLIDER_H

#include <QObject>
#include <QSlider>


class QHorSlider : public QSlider
{
    Q_OBJECT


public:
    QHorSlider(QWidget *parent = nullptr);
    ~QHorSlider();

signals:
    void ValueChanged();

protected:
    virtual void mousePressEvent(QMouseEvent *event);
    virtual void mouseReleaseEvent(QMouseEvent *event);

    bool            m_bLButtonDown;

};

#endif // QHORSLIDER_H
#include "QHorSlider.h"
#include <QSlider>
#include <QDebug>
#include <QMouseEvent>

QHorSlider::QHorSlider(QWidget* parent)
    : QSlider(parent)
{

}

QHorSlider::~QHorSlider()
{

}

void QHorSlider::mousePressEvent(QMouseEvent *event)
{
    //获取当前点击位置,得到的这个鼠标坐标是相对于当前QSlider的坐标
    int currentX = event->pos().x();

    //获取当前点击的位置占整个Slider的百分比
    double per = currentX *1.0 /this->width();

    //利用算得的百分比得到具体数字
    int value = per*(this->maximum() - this->minimum()) + this->minimum();

    //设定滑动条位置
    this->setValue(value);

    //滑动条移动事件等事件也用到了mousePressEvent,加这句话是为了不对其产生影响,是的Slider能正常相应其他鼠标事件
    QSlider::mousePressEvent(event);
}

void QHorSlider::mouseReleaseEvent(QMouseEvent *event)
{
    QSlider::mouseReleaseEvent(event);

    emit ValueChanged();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();

    void OnSliderValueChanged();

private:
    Ui::MainWindow *ui;



    int             m_nLast;
};

#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QMessageBox>
#include <QTimer>
#include "QHorSlider.h"


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    m_nLast(0)
{
    ui->setupUi(this);

    ui->horizontalSlider->setRange(0, 100);
    ui->horizontalSlider->setSingleStep(1);
    ui->horizontalSlider->setPageStep(1);
    ui->horizontalSlider->setTracking(false);
    ui->horizontalSlider->setCursor(QCursor(Qt::PointingHandCursor));

    connect(ui->horizontalSlider, &QHorSlider::ValueChanged, this, &MainWindow::OnSliderValueChanged);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_pushButton_clicked()
{
    ui->horizontalSlider->blockSignals(true);
    ui->horizontalSlider->setValue(m_nLast);
    ui->horizontalSlider->blockSignals(false);
}

void MainWindow::OnSliderValueChanged()
{
    qDebug() << ui->horizontalSlider->value();

    QMessageBox::information(this, "tip", "ok");
    ui->horizontalSlider->blockSignals(true);
    ui->horizontalSlider->setValue(m_nLast);
    ui->horizontalSlider->blockSignals(false);
}

 

©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页