Groove width of the Qtslider is bigger than the maximum number of tick marks
-
I am trying to make a few Qt sliders inside a scrollable area using Pyqt5. The sliders work fine, but after some certain amount of Max value (if I put tick value
variable_interval
equal301
then it works but it doesn't work if I put601
numbers of tick) of the slider, the tick marks don't appear evenly across the whole groove. I will have to adjust the tick marks and the groove through coding. Please check the GIF.If anyone has a specific idea how to correct it.
The Minimal Reproducable Example for the slider looks as follows and one can just change in the value of
variable_interval
to change the number of total slider ticks :#!/usr/bin/env python import cv2 import numpy as np import PyQt5.QtGui from PyQt5.QtCore import * from PyQt5.QtCore import QDir, Qt, QUrl from PyQt5.QtMultimedia import QMediaContent, QMediaPlayer from PyQt5.QtMultimediaWidgets import QVideoWidget from PyQt5.QtWidgets import (QApplication, QFileDialog, QHBoxLayout, QLabel, QStyleOptionSlider, QPushButton, QSlider, QSizePolicy, QStyle, QVBoxLayout, QWidget, QMainWindow, QAction, QShortcut, QCheckBox, QGridLayout, qApp, QScrollArea,QProxyStyle,QLayout) from PyQt5.QtGui import * import sys import time import os import datetime from datetime import timedelta import math variable_interval=701 ############ evenly distribute my intervals between variable_interval of numbers ############# def line_space(start, stop, n): temp_list = [start] if not (n % 2) == 0: step = ((stop - start) / (n - 1)).__round__() if step * (n - 1) < stop: step = math.ceil(((stop - start) / (n - 1))) odd = False else: step = ((stop - start) / (n - 2)).__round__() odd = True val = start for i in range(n - 1): val = val + step if odd and i == n - 2: continue temp_list.append(val) return temp_list ############################################### my slider class ################################ class LabeledSlider(QWidget): def __init__(self, minimum, maximum, interval=1, orientation=Qt.Horizontal, labels=None,levels=None, parent=None): super(LabeledSlider, self).__init__(parent=parent) self.slider_size=maximum self.maximum_=maximum self.minimum_=minimum self.interval_=interval self.changePaint=True self.orientation=orientation self.labels=labels self.levels=levels self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) if labels is not None: if not isinstance(labels, (tuple, list)): raise Exception("<labels> is a list or tuple.") if len(labels) != len(self.levels): raise Exception("Size of <labels> doesn't match levels.") self.levels=list(zip(self.levels ,self.labels)) #print(self.levels) else: self.levels=list(zip(self.levels,map(str,self.levels))) #print(self.levels) if orientation==Qt.Horizontal: self.layout=QVBoxLayout(self) self.layout.setSizeConstraint(QLayout.SetMinimumSize) self.layout.addStretch() else: raise Exception("<orientation> wrong.") # gives some space to print labels self.left_margin=10 self.top_margin=10 self.right_margin=10 self.bottom_margin=10 #self.SizeHint() self.layout.setContentsMargins(self.left_margin,self.top_margin, self.right_margin,self.bottom_margin) self.sl=QSlider(orientation, self) self.sl.setMinimum(self.minimum_) self.sl.setMaximum(self.maximum_) self.sl.setMinimumWidth(80*variable_interval) #self.sl.setMinimumHeight(100) self.sl.setTickInterval(self.interval_+1) self.sl.setSingleStep(1) self.sl.setTickPosition(QSlider.TicksBelow) self.sl.sizeHint() self.sl.setValue(minimum) self.layout.addWidget(self.sl) return class VideoWindow(QMainWindow): def __init__(self, parent=None): super(VideoWindow, self).__init__(parent) self.setWindowTitle("Video Analyser") self.setWindowIcon(QIcon("icon.png")) end_point_=67000 self.video_interval = line_space(0, 67000, variable_interval) interval=self.video_interval[1] - self.video_interval[0] self.labels=[] self.levels=[] for i in self.video_interval: self.levels.append(int(i)) #make_str="00:"+"{0:0=2d}".format(i) m, s = divmod(i, 60) h, m = divmod(m, 60) make_str=f'{h:d}:{m:02d}:{s:02d}' self.labels.append(make_str) self.positionSlider=LabeledSlider(0, end_point_ , interval, orientation=Qt.Horizontal, labels=self.labels,levels=self.levels) self.positionSlider2=LabeledSlider(0, end_point_ , interval, orientation=Qt.Horizontal, labels=self.labels,levels=self.levels) self.positionSlider3=LabeledSlider(0, end_point_ , interval, orientation=Qt.Horizontal, labels=self.labels,levels=self.levels) # Create a widget for window contents wid = QWidget(self) self.setCentralWidget(wid) widget_Slider = QWidget() controlLayout_ = QVBoxLayout(widget_Slider) #controlLayout_.addStretch() scroll = QScrollArea() scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) scroll.setWidgetResizable(True) scroll.setWidget(widget_Slider) controlLayout_.setContentsMargins(20, 20, 20, 20) controlLayout_.addWidget(self.positionSlider) controlLayout_.addWidget(self.positionSlider2) controlLayout_.addWidget(self.positionSlider3) # Create layouts to place inside widget controlLayout = QVBoxLayout() controlLayout.addWidget(scroll) mainScreen = QGridLayout() mainScreen.addLayout(controlLayout, 2, 0) # Set widget to contain window contents wid.setLayout(mainScreen) if __name__ == '__main__': app = QApplication(sys.argv) player = VideoWindow() player.showMaximized() sys.exit(app.exec_())
-
Hi and welcome to devnet,
You marked the thread as solved (glad you found a solution by the way), would you mind explaining what you did to fix it ?