第一部分:因为项目需要美化一个Slider控件,UI设计,后来发现是一个组合控件,需要自己重新搞一下,而且需要显示当前的Slider的值,这个组合控件是布局在一个大的WIdget上面的,直接摆放的,直接上UI设计的效果图:
该图由一个QSlider和两个按钮组成,按钮点击每次增加的固定步幅,滑块可以平滑的从1-100,功能应该是正常的滑块功能。
代码为正常添加一个QSlider和两个button
void CustomWidget::initUI()
{
m_plusBtn = new QPushButton;
m_minusBtn = new QPushButton;
m_slider = new CustomSlider(Qt::Horizontal);
m_slider->setValue(m_slider->maximum());
m_plusBtn->setStyleSheet("width:20px;height:20px;outline:none;border-image: url(:/resource/Resources/MainWindow/plus.png)");
m_minusBtn->setStyleSheet("width:20px;height:20px;outline:none;border-image: url(:/resource/Resources/MainWindow/minus.png)");
m_slider->setStyleSheet("QSlider::groove:horizontal{ \
height: 12px; \
left: 5px; \
right: 5px; \
border-image: url(:/resource/Resources/MainWindow/glide.png);\
} \
QSlider::handle:horizontal{ \
border-radius: 5px; \
width: 15px; \
height: 5px; \
margin-top: -1px; \
margin-left: -5px; \
margin-bottom: 2px; \
margin-right: -5px; \
border-image:url(:/resource/Resources/MainWindow/slider.png);} \
QSlider::sub-page:horizontal{border-image: url(:/resource/Resources/MainWindow/original.png);}");
QHBoxLayout *layout = new QHBoxLayout;
layout->addWidget(m_minusBtn);
layout->addWidget(m_slider);
layout->addWidget(m_plusBtn);
setLayout(layout);
connect(m_plusBtn, &QPushButton::clicked, this, &CustomWidget::plusClick);
connect(m_minusBtn, &QPushButton::clicked, this, &CustomWidget::minusClick);
connect(m_slider, &CustomSlider::valueChanged, this, &CustomWidget::sliderValue);
qDebug() << m_slider->maximum();
}
连个button分别连接信号槽即可:
void CustomWidget::plusClick()
{
if (m_slider->value() < m_slider->maximum())
{
m_slider->setValue(m_slider->value() + 5);
}
}
void CustomWidget::minusClick()
{
if (m_slider->value() > 0)
{
m_slider->setValue(m_slider->value() - 5);
}
}
第二部分:项目需求发生了变动,需要显示滑块当前的值,即在滑块上方,放置一个标签,显示当前滑块的值。效果图如下:
之前在网上找到一种方法,在slider内部,放置一个QLabel,连接valuechange的信号,更改label的位置,代码如下:
void CustomSlider::valueChange(int value)
{
m_displayLabel->setText(QString::number(value));
m_displayLabel->move((this->width()-m_displayLabel->width())*this->value()/(this->maximum()-this->minimum()),0);
}
但是在组合控件内部防止标签影响到了控件的整体布局,并且标签的大小,取决于控件的大小限制,效果如下:
因此重新查找计算slider的handle位置的方式,重新计算。查找源代码,在qslider.cpp中
找到了这一行代码,通过style获取handle的位置,以你次在外面连接value的槽函数,
connect(m_customWidget, &CustomWidget::sliderValue, this, &CenterWidget::position);
void CenterWidget::position(int position)
{
QStyleOptionSlider opt;
m_customWidget->getSlider()->initOption(&opt);
QRect handleRect = m_customWidget->getSlider()->style()->subControlRect(QStyle::CC_Slider, &opt, QStyle::SC_SliderHandle, m_customWidget->getSlider());
m_positionLabel->setText(QString::number(position));
QPoint point(handleRect.x(), m_customWidget->y());
m_positionLabel->move(this->mapToGlobal(point));
}
因为界面层级嵌套比较深,因此用了一个getSlider()的函数,把slider控件传递出去。在最外层做效果,你也可以直接封装成一个控件使用。最终效果如下:
有什么问题,可以直接加QQ:443932257或者微信hboxlayout联系。