转载自[一去、二三里]的Qt 之 QSlider
简述
QSlider 部件提供了一个垂直或水平滑动条。
滑块是一个用于控制有界值的典型部件。它允许用户沿水平或垂直方向移动滑块,并将滑块所在的位置转换成一个合法范围内的值。
详细描述
QSlider 很少有自己的函数,大部分功能在 QAbstractSlider 中。最有用的函数是 setValue(),用来设置滑块的当前值;triggerAction() 来模拟点击的效果(对快捷键有用),setSingleStep()、setPageStep() 用来设置步长,setMinimum() 和 setMaximum() 用于定义滚动条的范围。
QSlider 提供了一些方法来控制刻度标记。可以使用 setTickPosition() 来表示刻度标记的位置,使用 setTickInterval() 来指定刻度的间隔;当前设置的刻度位置和间隔可以分别使用 tickPosition() 和 tickInterval() 函数来查询。
QSlider 继承了一组全面的信号:
信号 | 描述 |
---|---|
valueChanged() | 当滑块的值发生了改变,发射此信号。tracking()确定在用户交互时,是否发出此信号。 |
sliderPressed() | 当用户按下滑块,发射此信号。 |
sliderMoved() | 当用户拖动滑块,发射此信号。 |
sliderReleased() | 当用户释放滑块,发射此信号。 |
注意:QSlider只提供整数范围。另外,尽管QSlider可以处理非常大的数字,但是对于用户来说,难以准确使用很大范围的滑块。
滑块接受Tab键的焦点,并同时提供了一个鼠标滚轮和键盘接口。键盘接口如下:
- Left/Right 移动水平滑块一个步长。
- Up/Down 移动垂直滑块一个步长。
- PageUp 上移一页。
- PageDown 下移一页。
- Home 移动至起始位置(最小值)。
- End 移动至结束位置(最大值)
刻度位置
枚举 QSlider::TickPosition
这个枚举指定刻度线相对于滑块和用户操作的位置。
常量 | 值 | 描述 |
---|---|---|
QSlider::NoTicks | 0 | 不绘制任何刻度线 |
QSlider::TicksBothSides | 3 | 在滑块的两侧绘制刻度线 |
QSlider::TicksAbove | 1 | 在(水平)滑块上方绘制刻度线 |
QSlider::TicksBelow | 2 | 在(水平)滑块下方绘制刻度线 |
QSlider::TicksLeft | TicksAbove | 在(垂直)滑块左侧绘制刻度线 |
QSlider::TicksRight | TicksBelow | 在(垂直)滑块右侧绘制刻度线 |
基本使用
下面我们来看一个示例。
int nMin = 0;
int nMax = 200;
int nSingleStep = 10;
// 微调框
QSpinBox *pSpinBox = new QSpinBox(this);
pSpinBox->setMinimum(nMin); // 最小值
pSpinBox->setMaximum(nMax); // 最大值
pSpinBox->setSingleStep(nSingleStep); // 步长
// 滑动条
QSlider *pSlider = new QSlider(this);
pSlider->setOrientation(Qt::Horizontal); // 水平方向
pSlider->setMinimum(nMin); // 最小值
pSlider->setMaximum(nMax); // 最大值
pSlider->setSingleStep(nSingleStep); // 步长
// 连接信号槽(相互改变)
connect(pSpinBox, SIGNAL(valueChanged(int)), pSlider, SLOT(setValue(int)));
connect(pSlider, SIGNAL(valueChanged(int)), pSpinBox, SLOT(setValue(int)));
pSpinBox->setValue(10);
通过 setMinimum() 与 setMaximum() 函数,我们将取固定到一个合适的范围(0 - 200),连接信号槽后,当 QSpinBox 的值发生改变时,QSlider 的值也会发生相应变化;反之亦然。最后,我们使用 setValue() 将 QSpinBox 的值设置为 10,由于信号槽已经连接,所以这时 QSlider 的值也会发生改变。
QSS
样式一并奉上:
QSlider::groove:horizontal {
height: 6px;
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 rgb(124, 124, 124), stop: 1.0 rgb(72, 71, 71));
}
QSlider::handle:horizontal {
1px;
background: rgb(0, 160, 230);
margin: -6px 0px -6px 0px;
border-radius: 9px;
}
刻度位置及间隔
为了演示效果,这里我们不再采用QSS样式控制。
QSlider *pSlider = new QSlider(this);
pSlider->setOrientation(Qt::Horizontal); // 水平方向
pSlider->setMinimum(nMin); // 最小值
pSlider->setMaximum(nMax); // 最大值
pSlider->setSingleStep(nSingleStep); // 步长
// pSlider->setTickInterval(40); // 设置刻度间隔
pSlider->setTickPosition(QSlider::TicksAbove); //刻度在上方
由于我们的取值范围是:0 - 200,步长为 10。所以,在绘制刻度的时候,一共有 21 个刻度点(从 0 开始,每隔步长 10 绘制一个点,到 200 处结束)。
扩展:各种样式表设置
样式表1
/* 首先是设置主体 */
QSlider{
border-color: #bcbcbc;
}
QSlider::groove:horizontal {
border: 1px solid #999999;
height: 1px;
margin: 0px 0;
left: 5px; right: 5px;
}
/* 设置中间的那个滑动的键 */
QSlider::handle:horizontal {
border: 0px ;
border-image: url(:/NiceTalk/Images/Setting/volume_nor.png);
15px;
margin: -7px -7px -7px -7px;
}
/* 还没有滑上去的地方 */
QSlider::add-page:horizontal{
background: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 #bcbcbc, stop:0.25 #bcbcbc, stop:0.5 #bcbcbc, stop:1 #bcbcbc);
}
/* 已经划过的从地方 */
QSlider::sub-page:horizontal{
background: qlineargradient(spread:pad, x1:0, y1:1, x2:0, y2:0, stop:0 #439cf3, stop:0.25 #439cf3, stop:0.5 #439cf3, stop:1 #439cf3);
}
样式表2
其实,竖直的和水平的一模一样,只是变了名称而已。
QSlider{
border-color: #cbcbcb;
}
QSlider::groove:vertical {
background: #cbcbcb;
6px;
border-radius: 1px;
padding-left:-1px;
padding-right:-1px;
padding-top:-1px;
padding-bottom:-1px;
}
QSlider::sub-page:vertical {
background: #cbcbcb;
border-radius: 2px;
}
QSlider::add-page:vertical {
background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 #439cf4, stop:1 #439cf4);
background: qlineargradient(x1: 0, y1: 0.2, x2: 1, y2: 1,
stop: 0 #439cf4, stop: 1 #439cf4);
10px;
border-radius: 2px;
}
QSlider::handle:vertical
{
border-image: url(:/NiceTalk/Images/Setting/volume_nor.png);
margin: -2px -7px -2px -7px;
height: 17px;
}
样式表3
QSlider::groove:horizontal {
border: 0px solid #bbb;
}
QSlider::sub-page:horizontal {
background: rgb(235,97,0);
border-radius: 0px;
margin-top:8px;
margin-bottom:8px;
}
QSlider::add-page:horizontal {
background: rgb(255,255, 255);
border: 0px solid #777;
border-radius: 2px;
margin-top:8px;
margin-bottom:8px;
}
QSlider::handle:horizontal {
background: rgb(255,153,102);
border: 1px solid rgb(255,153,102);
14px;
height:10px;
border-radius: 7px;
margin-top:2px;
margin-bottom:2px;
}
QSlider::handle:horizontal:hover {
background: rgb(255,128,6);
border: 1px solid rgba(102,102,102,102);
border-radius: 7px;
}
QSlider::sub-page:horizontal:disabled {
background: #bbb;
border-color: #999;
}
QSlider::add-page:horizontal:disabled {
background: #eee;
border-color: #999;
}
QSlider::handle:horizontal:disabled {
background: #eee;
border: 1px solid #aaa;
border-radius: 4px;
}
样式表4
/* 以下是槽 */
QSlider::groove:horizontal{
background:#aaaaaa;
height:24px;
border-radius:10px;
}
/* 设置中间的那个滑动的键 */
QSlider::handle:horizontal{
42px;
margin-top: -9px;
margin-bottom:-9px;
border-radius: 18px;
background: #f8f8f8;
}
/* 已经划过的从地方 */
QSlider::sub-page:horizontal{
border-radius:10px;
background: qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #5599FF, stop:1 #498ff8);
}
扩展:鼠标点击进行滑动条滑块定位
方法一:使用事件过滤器。
// 鼠标点击进行滑动条滑块定位
bool Device::eventFilter(QObject *obj, QEvent *event)
{
if(obj==pSlider_l)
{
if (event->type()==QEvent::MouseButtonPress)
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
if (mouseEvent->button() == Qt::LeftButton)
{
int dur = pSlider_l->maximum() - pSlider_l->minimum();
int pos = pSlider_l->minimum() + dur * ((double)mouseEvent->x() / pSlider_l->width());
if(pos < (pSlider_l->sliderPosition())||pos > (pSlider_l->sliderPosition()))
{
pSlider_l->setValue(pos);
}
}
}
}
return QObject::eventFilter(obj,event);
}
方法二:自定义鼠标点击事件。
// 方法是鼠标点击事件
void XSlider::mousePressEvent(QMouseEvent *e)
{
// 向上父控件传递鼠标事件;否则,鼠标其他事件会失灵
QSlider::mousePressEvent(e);
// 百分比
double p = (double)e->pos().x() / (double)width();
int val = p*(maximum()-minimum())+minimum();
this->setValue(val);
}
参考:
qt中QScrollBar/QSlider鼠标点击滑条不能到达所点击的位置,只移动step距离修改