是否有可能扩大围绕QSlider的绘制区域

问题描述 投票:4回答:3

我的目标是有在Python 3刻度线和刻度标记使用PySide2模块自定义QSlider。为了做到这一点我编辑QSlider类的默认的paintEvent在派生类中。然而,事实证明,该可打印区域是有限的,顶部/底部的标签我放置被裁剪(参见图)。我用它来生成这些滑块的代码如下:

import sys
from PySide2.QtCore import *
from PySide2.QtWidgets import *
from PySide2.QtGui import *

slider_x = 150
slider_y = 450
slider_step = [0.01, 0.1, 1, 10, 100]  # in microns


class MySlider(QSlider):
    def __init__(self, type, parent=None):
        super(MySlider, self).__init__(parent)
        self.Type = type

    def paintEvent(self, event):
        super(MySlider, self).paintEvent(event)
        qp = QPainter(self)
        pen = QPen()
        pen.setWidth(2)
        pen.setColor(Qt.red)

        qp.setPen(pen)
        font = QFont('Times', 10)
        qp.setFont(font)
        self.setContentsMargins(50, 50, 50, 50)
        # size = self.size()
        # print(size)
        # print("margins", self.getContentsMargins())
        # print(self.getContentsMargins())
        # print(self.contentsRect())
        contents = self.contentsRect()
        self.setFixedSize(QSize(slider_x, slider_y))
        max_slider = self.maximum()
        y_inc = 0
        for i in range(max_slider):
            qp.drawText(contents.x() - font.pointSize(), y_inc + font.pointSize() / 2, '{0:2}'.format(slider_step[i]))
            qp.drawLine(contents.x() + font.pointSize(), y_inc, contents.x() + contents.width(), y_inc)
            y_inc += slider_y/4


class Window(QWidget):
    """ Inherits from QWidget """
    def __init__(self):
        super().__init__()
        self.title = 'Control Stages'
        self.left = 10
        self.top = 10
        self.width = 320
        self.height = 100
        self.AxesMapping = [0, 1, 2, 3]
        self.initUI()

    def initUI(self):
        """ Initializes the GUI either using the grid layout or the absolute position layout"""
        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        Comp4 = self.createSlider("step_size")
        Comp5 = self.createSlider("speed")
        windowLayout = QGridLayout()
        windowLayout.setContentsMargins(50, 50, 50, 50)
        HGroupBox = QGroupBox()
        layout = QGridLayout()
        layout.addWidget(Comp4, 0, 0)
        layout.addWidget(Comp5, 0, 1)
        HGroupBox.setLayout(layout)
        HGroupBox.setFixedSize(QSize(740, 480))
        windowLayout.addWidget(HGroupBox, 0, 0)
        self.setLayout(windowLayout)
        self.show()

    def createSlider(self, variant):
        Slider = MySlider(Qt.Vertical)
        Slider.Type = variant
        Slider.setMaximum(5)
        Slider.setMinimum(1)
        Slider.setSingleStep(1)
        Slider.setTickInterval(1)
        Slider.valueChanged.connect(lambda: self.sliderChanged(Slider))
        return Slider

    @staticmethod
    def sliderChanged(Slider):
        print("Slider value changed to ", Slider.value(), "slider type is ", Slider.Type)
        if Slider.Type == "step_size":
            print("this is a step size slider")
        elif Slider.Type == "speed":
            print("this is a speed slider")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = Window()
    sys.exit(app.exec_())

是否有可能扩大绘制区域周围的QSlider如果是的话我怎么能达到这个效果?你可以看到,红色标签旁边的第一个和最后刻度线显示不正确的截图,他们被剪切(即在第一跳标签1和0缺少标签0.01的顶部)。

enter image description here

编辑:尝试提出的解决方案仍然是顶部标签的一部分后,修剪掉。下面第二个版本仍然是在Windows 10的64位与PySide2 5.12.0和Python 3.6.6相似。

EDIT2我有一个双引导系统,所以我使用Python 3.5.2 / PySide 5.12.0试过在Ubuntu 16.04.3 LTS和它的工作权利开箱的。这是从那里的截图,但不幸的是它在Windows上运行。

enter image description here

python python-3.x pyside2 qslider
3个回答
4
投票

我的建议是,你调查是由QSlider继承QAbstractSlider。它包含一个名为triggerAction方法(SliderToMaximum值为6),其可用于当set the Slider Positionaction is triggered

语法触发动作

 QAbstractSlider.triggerAction (self, SliderAction action)

对于SliderAction的值如下:

QAbstractSlider.SliderNoAction 0 QAbstractSlider.SliderSingleStepAdd 1

QAbstractSlider.SliderSingleStepSub 2

QAbstractSlider.SliderPageStepAdd 3

QAbstractSlider.SliderPageStepSub 4

QAbstractSlider.SliderToMinimum 5

QAbstractSlider.SliderToMaximum 6

QAbstractSlider.SliderMove 7

(Qazxswpoi)

使用source,您可以使用调用这些方法

PySide2

要么

PySide2.QtWidgets.QAbstractSlider.maximum()  //returns the value of the maximum

3
投票

如果我这样做是正确,你想要的蜱是在顶部和底部可见,因为他们似乎是“腰斩”,由于利润。我认为这是假设利润率正确设置为零或类似的东西,小部件的结果,你可以玩换号,看到这个效果。 (我想移动的利润率并没有成功)

现在,随着一个PySide2.QtWidgets.QAbstractSlider.setMaximum(arg) // pass your own value ,我发现,要实现类似的东西似乎是棘手的,并且可以基于该old postminimummaximum公式的基础蜱。

由于在底部刻度将是主要部件下,你可以添加一个特殊的条件为它使其可见。

不想粘贴整个代码,但你只需要你的循环之前声明QSlideropt。计算handle位置内,并用它来代替你的y

y_inc

def paintEvent(self, event): super(MySlider, self).paintEvent(event) qp = QPainter(self) pen = QPen() pen.setWidth(2) pen.setColor(Qt.red) qp.setPen(pen) font = QFont('Times', 10) qp.setFont(font) self.setContentsMargins(50, 50, 50, 50) # size = self.size() # print(size) # print("margins", self.getContentsMargins()) # print(self.getContentsMargins()) # print(self.contentsRect()) contents = self.contentsRect() self.setFixedSize(QSize(slider_x, slider_y)) # New code max_slider = self.maximum() min_slider = self.minimum() len_slider = max_slider - min_slider height = self.height() opt = QStyleOptionSlider() handle = self.style().subControlRect(QStyle.CC_Slider, opt, QStyle.SC_SliderHandle, self) handle_height = handle.height() # Add +10 on windows (workarount) height_diff = height - handle_height point_size = font.pointSize() for i in range(max_slider): y = round(((1 - i / len_slider) * height_diff + (handle_height / 2.0))) - 1 # Trick for the tick at the bottom if i == 0: y = self.height() - handle_height/2.0 # To have the tick in the middle #y = height_diff # to shift it a bit qp.drawText(contents.x() - point_size, y + point_size / 2, '{0:2}'.format(slider_step[len_slider - i])) qp.drawLine(contents.x() + point_size, y, contents.x() + contents.width(), y)

编辑:有似乎是Windows上的约10单位忽视的上边距,这是IMHHO Qt中的错误。一种解决方法是更换:

enter image description here

handle_height = handle.height()

内部的handle_height = handle.height() + 10 方法。


2
投票

摆弄周围多后,我终于找到了解决办法。它包括造型床单和我以前尝试过。然而,当时我没能正确地执行它。 II保持微件的大小恒定,但降低了槽长度,以便能够以适合的可打印区域内的标签。完整的代码如下:

paintEvent
© www.soinside.com 2019 - 2024. All rights reserved.