带有刻度文本标签的 Qt 滑块小部件
Posted
技术标签:
【中文标题】带有刻度文本标签的 Qt 滑块小部件【英文标题】:Qt slider widget with tick text labels 【发布时间】:2014-12-26 20:53:59 【问题描述】:我正在寻找像 QSlider 这样的 Qt 小部件,但支持这样的文本刻度标签:
这个小部件我将用作模式切换器。你遇到过这样的事情吗?
【问题讨论】:
【参考方案1】:我会使用带有QLabel
(s) 的QSlider
,如下所示。我通常的免责声明是,您可能需要自己进行一些微调和调整。
main.cpp
#include <QMainWindow>
#include <QApplication>
#include <QGridLayout>
#include <QSlider>
#include <QLabel>
class MainWindow Q_DECL_FINAL : public QMainWindow
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = Q_NULLPTR) : QMainWindow(parent)
QSlider *slider = new QSlider(Qt::Horizontal, this);
slider->setRange(1, 4);
slider->setSingleStep(1);
QLabel *label1 = new QLabel("Novice", this);
QLabel *label2 = new QLabel("Intermediate", this);
QLabel *label3 = new QLabel("Advanced", this);
QLabel *label4 = new QLabel("Expert", this);
QGridLayout *layout = new QGridLayout;
layout->addWidget(slider, 0, 0, 1, 4);
layout->addWidget(label1, 1, 0, 1, 1);
layout->addWidget(label2, 1, 1, 1, 1);
layout->addWidget(label3, 1, 2, 1, 1);
layout->addWidget(label4, 1, 3, 1, 1);
setLayout(layout);
;
#include "main.moc"
int main(int argc, char **argv)
QApplication application(argc, argv);
MainWindow mainWindow;
mainWindow.show();
return application.exec();
main.pro
TEMPLATE = app
TARGET = main
QT += widgets
SOURCES += main.cpp
构建并运行
qmake && make && ./main
【讨论】:
【参考方案2】:您可以在git 中使用我扩展的 QSlider 类。
【讨论】:
干得好,但问题与 Ipapp 对垂直滑块的回答相同。刻度标签未与刻度对齐。 @brahmin 你提到的问题很容易通过在网格中使用两倍的列来解决,从第一列(而不是第 0 列)跨越滑块到右边的第二列(而不是最右边) ,然后跨越两列上的每个标签,最后为它们使用Qt::AlignHCenter
。如果有人感兴趣,我可以发布我对 @Ipapp 代码的修改以解决这个问题【参考方案3】:
我也有类似的需求,我最终通过覆盖paintEvent 来解决它。这是一个 PyQt 解决方案:
class Slider(QSlider):
"""Slider with labels (instead of tick marks) along each available position"""
def __init__(self, parent=None):
super(Slider, self).__init__(parent)
# this decides the range and the labels placed along the slider
self.values = ['one', 'two', 'three', 'four', 'five']
self.setOrientation(Qt.Horizontal)
self.setTickInterval(1)
self.setTickPosition(QSlider.NoTicks)
self.setSingleStep(1)
self.setRange(0, len(self.values) - 1)
self.setValue(0)
def paintEvent(self, event):
QSlider.paintEvent(self, event)
rect = self.geometry()
curr_value = str(self.value() / 1000.00)
round_value = round(float(curr_value), 2)
# start painter
painter = QPainter(self)
painter.setPen(QPen(Qt.black))
font_metrics = QFontMetrics(self.font())
font_width = font_metrics.boundingRect(str(round_value)).width()
for index, value in enumerate(self.values):
print(index, value)
# first and last position need a slightly different offset so the text doesn't get cut
if index == 0:
# first position
pos = QStyle.sliderPositionFromValue(self.minimum(), self.maximum(), index, self.width())
painter.drawText(QPoint(pos, rect.height()), value)
elif index == len(self.values) - 1:
# last position
pos = QStyle.sliderPositionFromValue(self.minimum(), self.maximum(), index, self.width())
painter.drawText(QPoint(pos - font_width, rect.height()), value)
else:
pos = QStyle.sliderPositionFromValue(self.minimum(), self.maximum(), index, self.width())
painter.drawText(QPoint(pos - font_width / 2.0, rect.height()), value)
最终看起来像这样:
【讨论】:
以上是关于带有刻度文本标签的 Qt 滑块小部件的主要内容,如果未能解决你的问题,请参考以下文章