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); }
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。