我正在尝试创建一个滚动条,后面有一个滑块,用于保存用户保存的最后一个值。为了更好地解释我的目的,我在下面创建了图片。
在图像中,中间的滑块应该保持用户应用的最后一个值,而主滑块(顶部的滑块)可以自由拖动。换句话说,当用户按下按钮或其他东西时,无法选择中间的那个,并且其值会更改为另一个的值。
到目前为止,我尝试了以下方法,但没有成功:
创建一个继承自QScrollBar的类,并在其中添加其他QScrollBar。
scrollbar.h
#ifndef SCROLLBAR_H
#define SCROLLBAR_H
#include <QScrollBar>
class ScrollBar : public QScrollBar
{
Q_OBJECT
public:
ScrollBar ( Qt::Orientation orientation, QWidget * parent = 0 );
void init();
void update();
private:
QScrollBar* subslider;
};
#endif // SCROLLBAR_H
scrollbar.cpp
#include "scrollbar.h"
ScrollBar::ScrollBar( Qt::Orientation orientation, QWidget * parent ) :
QScrollBar (orientation, parent) {
subslider = new QScrollBar(orientation, this);
}
void ScrollBar::init() {
subslider->setMaximum( QScrollBar::maximum() );
subslider->setMinimum( QScrollBar::minimum() );
subslider->setFixedSize( QScrollBar::size() );
subslider->setValue( QScrollBar::minimum() );
subslider->setEnabled(false);
subslider->setVisible(true);
}
void ScrollBar::update() {
subslider->setValue( QScrollBar::sliderPosition() );
}
创建一个继承自QScrollBar的类,并使用paintEvent
添加另一个滑块。
scrollbar.h
#ifndef SCROLLBAR_H
#define SCROLLBAR_H
#include <QScrollBar>
#include <QPaintEvent>
class ScrollBar : public QScrollBar
{
Q_OBJECT
public:
ScrollBar ( Qt::Orientation orientation, QWidget * parent = 0 );
void update();
private:
int scrollbar_pos;
signals:
protected:
void paintEvent( QPaintEvent* event );
};
#endif // SCROLLBAR_H
scrollbar.cpp
#include "scrollbar.h"
#include <QPainter>
ScrollBar::ScrollBar( Qt::Orientation orientation, QWidget * parent ) :
QScrollBar (orientation, parent) {
scrollbar_pos = 0;
}
void ScrollBar::update() {
subslider_pos = QScrollBar::sliderPosition();
}
void ScrollBar::paintEvent(QPaintEvent * event) {
// This calls the base class's paint calls
QScrollBar::paintEvent(event);
// The following is painted on top of it
QPainter p(this);
/**
* I think the code here should get the image used to display the slider
* and put it on the correct position.
*/
}
答案 0 :(得分:1)
我设法使用不同的方法解决问题。我使用CSS样式表手动配置滑块并创建了一个类似于滑块的按钮来表示最后保存的值。现在这堂课看起来像这样。
scrollbar.h
#ifndef SCROLLBAR_H
#define SCROLLBAR_H
#include <QSlider>
#include <QPaintEvent>
#include <QPushButton>
class ScrollBar : public QSlider
{
Q_OBJECT
public:
ScrollBar ( QWidget * parent = 0 );
~ScrollBar();
void init();
void update();
protected:
QPushButton* button;
protected slots:
void mousePressEvent();
};
#endif // SCROLLBAR_H
scrollbar.cpp
#include "scrollbar.h"
#include <QPainter>
ScrollBar::ScrollBar( QWidget * parent ) :
QSlider (Qt::Horizontal, parent) {
QSlider::setMaximum(100);
QSlider::setMinimum(0);
QSlider::setValue(50);
QSlider::setFixedSize(200, 20);
button = new QPushButton(this);
button->setObjectName("slider");
button->move(0, 3);
button->setEnabled(true);
button->setFocusPolicy(Qt::NoFocus);
connect(button, SIGNAL(pressed()), this, SLOT(mousePressEvent()));
}
void ScrollBar::update() {
std::cout << "Called update()" << std::endl;
// The following moves the false button
double delta = QSlider::sliderPosition() /
(double) (QSlider::maximum() - QSlider::minimum()) *
(QSlider::width() - 14);
button->move(delta, 3);
}
void ScrollBar::mousePressEvent() {
QPoint pos = button->pos();
pos.setX( pos.x() + 7 );
pos.setY(6);
QMouseEvent evt(QEvent::MouseButtonPress, pos, Qt::LeftButton,
Qt::LeftButton, Qt::NoModifier);
QSlider::mousePressEvent(&evt);
}
ScrollBar::~ScrollBar() {
}
slider.css
QSlider::groove:horizontal {
border: 1px solid #bbb;
background: white;
height: 10px;
border-radius: 4px;
}
QSlider::sub-page:horizontal {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #66e, stop: 1 #bbf);
background: qlineargradient(x1: 0, y1: 0.2, x2: 1, y2: 1,
stop: 0 #bbf, stop: 1 #55f);
border: 1px solid #777;
height: 10px;
border-radius: 4px;
}
QSlider::add-page:horizontal {
background: #fff;
border: 1px solid #777;
height: 10px;
border-radius: 4px;
}
QSlider::handle:horizontal {
background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
stop:0 #eee, stop:1 #ccc);
border: 1px solid #777;
width: 13px;
margin-top: -2px;
margin-bottom: -2px;
border-radius: 4px;
}
QSlider::handle:horizontal:hover {
background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
stop:0 #fff, stop:1 #ddd);
border: 1px solid #444;
border-radius: 4px;
}
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;
}
QPushButton#slider {
background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
stop:0 #ccc, stop:1 #aaa);
border: 1px solid #777;
max-width: 13px;
min-width: 13px;
max-height: 12px;
min-height: 12px;
border-radius: 4px;
}
添加小部件看起来像这样:
QFile file("slider.css");
file.open(QFile::ReadOnly);
QString style = file.readAll();
file.close();
ScrollBar* scroll = new ScrollBar(parent);
parent->setStyleSheet(style);
// or scroll->setStyleSheet(style); if the style should be added only to this widget
。 结果如下:
我必须按下按钮才能将鼠标事件传递给滑块,因为按钮位于按钮顶部。
修改强>
更清晰的解决方案是添加透明滚动条而不是按钮。
scrollbar.h
#ifndef SCROLLBAR_H
#define SCROLLBAR_H
#include <QSlider>
#include <QResizeEvent>
class ScrollBar : public QSlider
{
Q_OBJECT
public:
bool enabled;
ScrollBar ( QWidget * parent = 0 );
~ScrollBar();
void init();
void update();
void setValue(int);
void setFixedValue(int);
QSize sizeHint() const;
protected:
QSlider* slider_fixed;
QSlider* slider_top;
virtual void resizeEvent(QResizeEvent *evt);
};
#endif
scrollbar.cpp
#include "scrollbar.h"
#include <QFile>
ScrollBar::ScrollBar( QWidget * parent ) : QSlider (Qt::Horizontal, parent) {
QSlider::setMaximum(100);
QSlider::setMinimum(0);
QSlider::setValue(50);
slider_fixed = new QSlider(Qt::Horizontal, this);
slider_fixed->setMaximum( QSlider::maximum() );
slider_fixed->setMinimum( QSlider::minimum() );
slider_fixed->setValue( QSlider::minimum() );
slider_fixed->setObjectName("transparent_fixed");
slider_top = new QSlider(Qt::Horizontal, this);
slider_top->setMaximum( QSlider::maximum() );
slider_top->setMinimum( QSlider::minimum() );
slider_top->setValue( QSlider::sliderPosition() );
slider_top->setObjectName("transparent_top");
QFile file("slider.css");
file.open(QFile::ReadOnly);
QString style = file.readAll();
file.close();
QSlider::setStyleSheet(style);
QObject::connect(slider_top, SIGNAL(valueChanged(int)), this, SLOT(setValue(int)));
}
QSize ScrollBar::sizeHint() const {
return QSize(2000, 20);
}
void ScrollBar::resizeEvent(QResizeEvent *evt) {
int width = evt->size().width();
int height = evt->size().height();
slider_fixed->resize(width, height);
slider_top->resize(width, height);
}
void ScrollBar::setFixedValue(int value) {
slider_fixed->setValue( value );
}
void ScrollBar::setValue(int value) {
slider_top->setValue(value);
}
ScrollBar::~ScrollBar() {
}
slider.css
QSlider::groove:horizontal {
border: 1px solid #bbb;
background: white;
height: 10px;
border-radius: 4px;
}
QSlider::sub-page:horizontal {
background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1,
stop: 0 #66e, stop: 1 #bbf);
background: qlineargradient(x1: 0, y1: 0.2, x2: 1, y2: 1,
stop: 0 #bbf, stop: 1 #55f);
border: 1px solid #777;
height: 10px;
border-radius: 4px;
}
QSlider::add-page:horizontal {
background: #fff;
border: 1px solid #777;
height: 10px;
border-radius: 4px;
}
QSlider::handle:horizontal {
background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
stop:0 #eee, stop:1 #ccc);
border: 1px solid #777;
width: 13px;
margin-top: -2px;
margin-bottom: -2px;
border-radius: 4px;
}
QSlider::handle:horizontal:hover {
background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
stop:0 #fff, stop:1 #ddd);
border: 1px solid #444;
border-radius: 4px;
}
QSlider#transparent_fixed::groove:horizontal {
border: none;
background: transparent;
border-radius: 0px;
}
QSlider#transparent_fixed::sub-page:horizontal {
background: transparent;
border: none;
border-radius: 0px;
}
QSlider#transparent_fixed::add-page:horizontal {
background: transparent;
border: none;
border-radius: 0px;
}
QSlider#transparent_fixed::handle:horizontal {
background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
stop:0 #bbb, stop:1 #999);
}
QSlider#transparent_fixed::handle:horizontal:hover {
border: 1px solid #777;
}
QSlider#transparent_top::groove:horizontal {
border: none;
background: transparent;
border-radius: 0px;
}
QSlider#transparent_top::sub-page:horizontal {
background: transparent;
border: none;
border-radius: 0px;
}
QSlider#transparent_top::add-page:horizontal {
background: transparent;
border: none;
border-radius: 0px;
}