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

 更新时间:2022年11月10日 16:36:58   作者:在广州的阿杰  
这篇文章主要介绍了Qt界面中滑动条的实现方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

Qt界面实现滑动条

功能

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

效果

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)解决。

使用原QSlider

如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);
}

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

相关文章

  • C++ 使用 new 创建二维数组实例

    C++ 使用 new 创建二维数组实例

    这篇文章主要介绍了C++ 使用 new 创建二维数组实例的相关资料,需要的朋友可以参考下
    2023-01-01
  • C++实现简单走迷宫的代码

    C++实现简单走迷宫的代码

    这篇文章主要为大家详细介绍了C++实现简单走迷宫的代码,利用回溯法求解,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-05-05
  • C语言编程实现扫雷游戏

    C语言编程实现扫雷游戏

    这篇文章主要为大家详细介绍了C语言编程实现扫雷游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • C++中的std::async()详解

    C++中的std::async()详解

    这篇文章主要给大家介绍了关于C++中std::async()的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • 使用C语言实现本地socke通讯的方法

    使用C语言实现本地socke通讯的方法

    这篇文章主要介绍了 使用C语言实现本地socke通讯,代码分为服务器代码和客户端代码,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-12-12
  • C++中的ilst使用以及模拟实现

    C++中的ilst使用以及模拟实现

    list是一个类模板,加<类型>实例化才是具体的类,可以在任意位置进行插入和删除的序列式容器,本文将通过代码示例给大家介绍一下C++中的ilst使用以及模拟实现,需要的朋友可以参考下
    2023-08-08
  • 北邮计算机考研复试题的C语言解答精选

    北邮计算机考研复试题的C语言解答精选

    这篇文章主要介绍了北邮计算机考研复试题目的C语言解答精选,选自2012年的一些基础的上机题目,需要的朋友可以参考下
    2015-08-08
  • 一篇文章带你了解C++面向对象编程--继承

    一篇文章带你了解C++面向对象编程--继承

    这篇文章主要介绍了解析C++面对象编程--继承的运用,是C++入门学习中的基础知识,需要的朋友可以参考下,希望能够给你带来帮助
    2021-08-08
  • C++ 情怀游戏扫雷的实现流程详解

    C++ 情怀游戏扫雷的实现流程详解

    扫雷是电脑上很经典很经典的传统老游戏,从小编第一次摸到计算机开始就玩过扫雷,虽然当时并不理解玩法原理,但终是第一次玩电脑游戏,下面来从扫雷的前世今生讲起
    2021-11-11
  • C++实现LeetCode(136.单独的数字)

    C++实现LeetCode(136.单独的数字)

    这篇文章主要介绍了C++实现LeetCode(136.单独的数字),本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-07-07

最新评论