Qt界面中滑动条的实现方式

2022-11-10 17:39:45

目录Qt界面实现滑动条功能效果Qt滑动条解决点击和拖动问题使用原QSlider继承QSlider,重写事件函数Qt界面实现滑动条功能在窗体内放置一个滑动条slider、一个spinbox增减小控件,...

目录
Qt界面实现滑动条
功能
效果
Qt滑动条解决点击和拖动问题
使用原QSlider
继承QSlider,重写事件函数

Qt界面实现滑动条

功能

在窗体内放置一个滑动条slider、一个spin box增减小控件,一个设置中间值的按钮,一个将当前值通过qQebug打印到编译器上。使用弹簧和布局使界面更美观。

效果

Qt界面中滑动条的实现方式

Widget.h文件:

#pragma once

#include <QtWidgets/QWidget>
#include<QSlider>//滑动条头文件
#include<QSpinBox>//增减控件头文件
#include<QBoxLayout>//界面布局头文件,包含了水平布局<QHBoxLayout>和垂直布局<QvboxLayout>
#include<QSpacerItem>//弹簧头文件
#include<QPushButton>//按钮头文件
#include<QDebug>//qDebug输出头文件
#include "ui_Widget.h"//ui界面

class Widget : public QWidget
{
Q_OBJECT

public:
Widget(QWidget *parent = Q_NULLPTR);
QSlider *slider;//定义一个滑动条,在cpp文件的构建函数中设置属性,下列控件同
QSpinBox *box;//定义一个增减控件

QSpacerItem *spacer;//弹簧1
QSpacerItem *spacer2;//弹簧2

QPushButton *btn_setMedi;//设置中间值的按钮
QPushButton *btn_getValue;//打印当前值的按钮

private:
Ui::WidgetClass ui;
};

Widget.cpp:

#include "Widget.h"

Widget::Widget(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);

QSpinBox *box = new QSpinBox(this);
QSlider *slider = new QSlider(Qt::Horizontal,this);//Qt::Horizontal设置为水平的滑动条

QSpacerItem *spacer = new QSpacerItem(20, 20);  //弹簧的w和h为20,20
QSpacerItem *spacer2 = new QSpacerItem(20, 20);
QSpacerItem *spacer3 = new QSpacerItem(20, 20);
QSpacerItem *spacer4 = new QSpacerItem(20, 20);

QPushButton *btn_setMedi = new QPushButton("set median", this);//按钮文本为“set median”
QPushButton *btn_getValue = new QPushButton("get value", this);

QHBoxLayout *loyout = new QHBoxLayout;//相当于this->setLayout(loyout);定义一个水平布局
loyout->addItem(spacer);//添加弹簧用addItem
loyout->addwidget(box);//添加控件和按钮用addWidget
loyout->addWidget(slider);
loyout->addItem(spacer2);

QHBoxLayout *btnLayout = new QHBoxLayout;
btnLayout->addItem(spacer3);
btnLayout->addWidget(btn_setMedi);
btnLayout->addWidget(btn_getValue);
btnLayout->addItem(spacer4);

//垂直布局设置了this,让布局依赖在widget上
//前面的两个水平布局不用设置,因为水平布局依赖在了垂直布局上,只需最外层设置依赖
QVBoxLayout *vloyout = new QVBoxLayout(this);//添加垂直布局,把前面的两个水平布局放进来
vloyout->addLayout(loyout);
vloyout->addLayout(btnLayout);

this->setFixedSize(400, 300);//把窗体大小固定

//数值改变,滑动条跟着改变
//函数QSpinBox::valueChanged出现了函数重载(int或char),需要定义一个函数指针排除二义性
void (QSpinBox:: *box_signal ) (int) = &QSpinBox::valueChanged;
connect(box ,box_signal , slider, &QSlider::setValue);

//滑动条改变,数值跟着改变
connect(slider, &QSlider::valueChanged, box, &QSpinBox::setValue);

//设置中间值
//使用了Lambda表达式[](){}
connect(btn_setMedi, &QPushButton::clicked, [=]() {
slider->setValue(50);
});

//打印当前值
connect(btn_getValue, &QPushButton::clicked, [=]() {
qDebug() << box->value();
});
}

main.cpp:

#include "Widget.h"
#include <QtWidgets/QApplication>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}

Qt滑动条解决点击和拖动问题

QSlider 在点击非滑块部分时,不会直接到点击位置,而是一步一步执行,在项目中使用时会感觉不流畅。可以通过改变QSlider的鼠标点击事件(mousePressEvent)和鼠标移动事件(mouseMoveEvent)解决。

使用原QSlidhttp://www.cppcns.comer

如UI中使用verticalSlider,MySliderUI.h 头文件:

class MySliderUI : public QWidget
{
  Q_OBJECT
public:
  explicit MySliderUI(QWidget *parent = 0);
  ~MySliderUI();
protected:
  bool eventFilter(QObject *obj, QEvent *event);

private:
  Ui::EpsSliderUI *ui;
};

MySliderUI.cpp

MySliderUI::MySliderUI(QWidget *parent) :
  QWidget(parent)
{
  ui->slider->installEventFilter(this);
}

添加事件过滤,对QSlider的事件重新处理。

bool MySliderUI::eventFilter(QObject *obj, QEvent *event)
{
  if( obj == ui->slider)
  {
    if (event->type() == QEvent::MouseButtonPress)
    {
      QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
      if (mouseEvent->button() == Qt::LeftButton)
      {
        ui->slider->event(event);
        double pos = mouseEvent->pos().y() / (double)ui->slider->height();
       int value = pos * (ui->slider->maximum() - ui->slider->minimum())
            + ui->slider->minimum()+0.5;
        ui->slider->setValue(value);
        return true;
      }
    }
    else if (event->type() == QEvent::MouseButtonDblClick)
    {
      return true;
    }
    else if (event->type() == QEvent::MouseMove)
    {
      QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
      ui->slider->event(event);
      double pos = mouseEvent->pos().y() / (double)ui->slider->height();
      int value = pos * (ui->slider->maximum() - ui->slider->minimum())
           + ui->slider->minimum()+0.5;
      ui->slider->setValue(value);
      return true;
    }
  }
  return QObject::eventFilter(obj,event);
}

继承QSlider,重写事件函数

头文件

class MySlider : public QSlider
{
  Q_OBJECT
public:
  MySlider(QWidget *parent = nullptr);
  ~MySlider();

protected:
  void mousePressEvent(QMouseEvent *event); //单击
  void mouseMoveEvent(QMouseEvent *event);
};

实现文件

#include "myslider.h"
#include <QMouseEvent>

MySlider::MySlider(QWidget *parent)
  :QSlider (parent)
{
}

MySlider::~MySlider()
{
}

void MySlider::mousePressEvent(QMouseEvent *event)
{
  if (event->button() == Qt::LeftButton) //判断左键
  {
    //注意应先调用父类的鼠标点击处理事件,这样可以不影响拖动的情况
    QSlider::mousePressEvent(event);
    double pos = ((double)height() - event->pos().y()) / (double)height();
    int value = pos * (maximum() - minimum()) + minimum();
    setValue(value);
  }
}
void MySlider::mouseMoveEvent(QMouseEvent *event)
{
  //注意应先调用父类的鼠标点击处理事件,这样可以不影响拖动的情况
  QSlider::mouseMoveEvent(event);
  double pos = ((double)height() - event->pos().y()) / (double)height();
  int value = pos * (maximum() - minimum()) + minimum();
  setValue(value);
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。