欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Qt-Slider实例

程序员文章站 2022-07-13 17:34:54
...

      接着上节的内容,我们还是按照既定的目标,在对控件完成简单的介绍后我们需要介绍一个综合的实例,这样有助于我们更好的将理论与实践结合起来。

本节将述的Slider包含两个类:

1.SliserGroup是用户自定义控件,继承于QGroupBox类. 其内部包含 QSliderQScrollBarQDial.

2.主窗口包含QStackWidget和QGroupBox,其中QStackWidget相当于一个容器来容纳SliderGroup,QGroupBox包含几个控件,这些控件控制类似滑块的控件的行为。

#include <QWidget>
#include <QLabel>
#include <QSpinBox>
#include <QCheckBox>
#include <QComboBox>
#include <QGroupBox>
#include <QStackedWidget>
#include <QGridLayout>
#include <QHBoxLayout>
#include <QGridLayout>

#include "slidersgroup.h"
namespace Ui {
class SliderWidget;
}

class SliderWidget : public QWidget
{
    Q_OBJECT

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

private:
    Ui::SliderWidget *ui;
    QGroupBox *controlGroup;
    QLabel *minimumLabel;
    QLabel *maximumLabel;
    QLabel *currentLabel;
    QSpinBox *minimumSpinBox;
    QSpinBox *maximumSpinBox;
    QSpinBox *currentSpinBox;
    QCheckBox *invertedAppearance;
    QCheckBox *invertedKeyBindings;
    QComboBox *orientationCombo;

    QStackedWidget *stackWidget;
    SlidersGroup *horizontalSlider;
    SlidersGroup *verticalSlider;


};

#endif // SLIDERWIDGET_H

在其头文件中声明变量,可以看到horizontalSlider、verticalSlider两个私有成员,分别代表水平方向放置的组合slider和垂直方向放置的Slider。

minimumLabel = new QLabel(tr("M&inimum value:"));
minimumSpinBox = new QSpinBox();
minimumSpinBox->setRange(-100,100);
minimumLabel->setBuddy(minimumSpinBox);
invertedAppearance = new QCheckBox(tr("Inverted Appearance"));

maximumLabel = new QLabel(tr("M&aximum value:"));
maximumSpinBox = new QSpinBox();
maximumSpinBox->setRange(-100,100);
maximumLabel->setBuddy(maximumSpinBox);
invertedKeyBindings = new QCheckBox(tr("Inverted Key Bindings"));

currentLabel = new QLabel(tr("C&urrent value:"));
currentSpinBox = new QSpinBox();
currentLabel->setBuddy(currentSpinBox);

orientationCombo = new QComboBox();
orientationCombo->addItem(tr("Horizontal Slider"));
orientationCombo->addItem(tr("Vertical Slider"));

horizontalSlider = new SlidersGroup(Qt::Horizontal,tr("Horizontal"));
verticalSlider = new SlidersGroup(Qt::Vertical,tr("Vertical"));
stackWidget = new QStackedWidget();
stackWidget->addWidget(horizontalSlider);
stackWidget->addWidget(verticalSlider);

    connect(minimumSpinBox,QOverload<int>::of(&QSpinBox::valueChanged),horizontalSlider,&SlidersGroup::setMinimum);//当minmiSpinBox的值发生改变的时候需要设置sliderde最小值
    connect(minimumSpinBox,QOverload<int>::of(&QSpinBox::valueChanged),verticalSlider,&SlidersGroup::setMinimum);//同上,为什么要设置两次,是因为stackwidget中包含水平排列的SliderGroup和垂直放置的SliderGruop,所以需要同时更新

    connect(maximumSpinBox,QOverload<int>::of(&QSpinBox::valueChanged),horizontalSlider,&SlidersGroup::setMaximum);
    connect(maximumSpinBox,QOverload<int>::of(&QSpinBox::valueChanged),verticalSlider,&SlidersGroup::setMaximum);

    connect(horizontalSlider,&SlidersGroup::ValueChanged,currentSpinBox,&QSpinBox::setValue);
    connect(verticalSlider,&SlidersGroup::ValueChanged,currentSpinBox,&QSpinBox::setValue);

    connect(orientationCombo,QOverload<int>::of(&QComboBox::activated),stackWidget,&QStackedWidget::setCurrentIndex);//当切换方向是需要改变stackwidget中的内容,setCurrentIndex函数可以切换要显示的当前内容。

    connect(invertedAppearance,&QCheckBox::toggled,horizontalSlider,&SlidersGroup::invertAppearance);
    connect(invertedAppearance,&QCheckBox::toggled,verticalSlider,&SlidersGroup::invertAppearance);

    connect(currentSpinBox,QOverload<int>::of(&QSpinBox::valueChanged),horizontalSlider,&SlidersGroup::setValue);
    connect(currentSpinBox,QOverload<int>::of(&QSpinBox::valueChanged),horizontalSlider,&SlidersGroup::setValue);

    connect(invertedKeyBindings,&QCheckBox::toggled,horizontalSlider,&SlidersGroup::invertKeyBindings);
    connect(invertedKeyBindings,&QCheckBox::toggled,verticalSlider,&SlidersGroup::invertKeyBindings);

    QGridLayout *controlLayout = new QGridLayout();
    controlLayout->addWidget(minimumLabel,0,0);
    controlLayout->addWidget(minimumSpinBox,0,1);
    controlLayout->addWidget(invertedAppearance,0,2);
    controlLayout->addWidget(maximumLabel,1,0);
    controlLayout->addWidget(maximumSpinBox,1,1);
    controlLayout->addWidget(invertedKeyBindings,1,2);
    controlLayout->addWidget(currentLabel,2,0);
    controlLayout->addWidget(currentSpinBox,2,1);
    controlLayout->addWidget(orientationCombo,3,0,1,3);
    controlGroup->setLayout(controlLayout);

    QHBoxLayout *mainLayout = new QHBoxLayout();
    mainLayout->addWidget(controlGroup);
    mainLayout->addWidget(stackWidget);
    setLayout(mainLayout);

    minimumSpinBox->setValue(0);//设置当前值
    maximumSpinBox->setValue(100);//设置当前值
    currentSpinBox->setValue(5);//设置当前值

 SliderGruop.h如下:

#ifndef SLIDERSGROUP_H
#define SLIDERSGROUP_H

#include <QGroupBox>
#include <QSlider>
#include <QScrollBar>
#include <QDial>
#include <QBoxLayout>

class SlidersGroup : public QGroupBox
{
    Q_OBJECT
public:
    explicit SlidersGroup(Qt::Orientation Orientation,const QString &title,QWidget *parent = nullptr);

signals:
    void ValueChanged(int);
public slots:
public slots:
    void setValue(int value);
    void setMinimum(int value);
    void setMaximum(int value);
    void invertAppearance(bool invert);
    void invertKeyBindings(bool invert);
private:
    QSlider *slider;
    QScrollBar *scrollBar;
    QDial *dial;
};

#endif // SLIDERSGROUP_H

   SliderGruop.cpp如下:

#include "slidersgroup.h"

SlidersGroup::SlidersGroup(Qt::Orientation Orientation,const QString &title,QWidget *parent) :
    QGroupBox(title,parent)
{

    slider = new QSlider(Orientation);
    slider->setFocusPolicy(Qt::StrongFocus);
    slider->setTickPosition(QSlider::TicksBothSides);
    slider->setTickInterval(10);
    slider->setSingleStep(1);

    scrollBar = new QScrollBar(Orientation);
    slider->setFocusPolicy(Qt::StrongFocus);

    dial = new QDial();
    slider->setFocusPolicy(Qt::StrongFocus);

    //主要是构成一个消息循环,只要一个发生改变其余两个也同时发生改变
    connect(slider,&QSlider::valueChanged,scrollBar,&QScrollBar::setValue);
    connect(scrollBar,&QScrollBar::valueChanged,dial,&QDial::setValue);
    connect(dial,&QDial::valueChanged,slider,&QSlider::setValue);
    
    //当slider的值发生改变的时候更新currentSpinBox
    connect(slider,&QSlider::valueChanged,this,&SlidersGroup::ValueChanged);

    QBoxLayout::Direction direction;
    if(Orientation == Qt::Horizontal)
        direction = QBoxLayout::TopToBottom;
    else
        direction = QBoxLayout::LeftToRight;
    QBoxLayout *mainLayout = new QBoxLayout(direction);
    mainLayout->addWidget(slider);
    mainLayout->addWidget(scrollBar);
    mainLayout->addWidget(dial);
    setLayout(mainLayout);
}
//设置Slider的当前值,由于前面构成了消息的循环,只要一个发生改变其余的都会发生改变,这样处理比较简单,要不就需要写三个槽函数来分别处理对应的值的更新
void SlidersGroup::setValue(int value)
{
    slider->setValue(value);
}
//设置最大值
void SlidersGroup::setMinimum(int value)
{
    slider->setMinimum(value);
    scrollBar->setMinimum(value);
    dial->setMinimum(value);
}
//设置最小值
void SlidersGroup::setMaximum(int value)
{
    slider->setMaximum(value);
    scrollBar->setMaximum(value);
    dial->setMaximum(value);
}
//保留滑块是否反转显示其值,若invert为True最大值和最小值的位置发生调换,否则左边为最小值,右边为最大值
void SlidersGroup::invertAppearance(bool invert)
{
    slider->setInvertedAppearance(invert);
    scrollBar->setInvertedAppearance(invert);
    dial->setInvertedAppearance(invert);
}

void SlidersGroup::invertKeyBindings(bool invert)
{
    slider->setInvertedControls(invert);//此属性保留滑块是否反转其控制盘和关键点事件。若invert为false,则鼠标滚轮向上滑则slider值递增、pageup按钮按住其值也递增,否则相反
    scrollBar->setInvertedControls(invert);
    dial->setInvertedControls(invert);
}

效果图如下:

Qt-Slider实例

相关标签: Qt软件开发