Vertical QScrollBar seems to have height 0
-
I cannot seem to fix it or even understand why this is happening. I have a list view with its vertical scrollbar. For some reason, handle of my sidebar just does not exist. If I have the list view outside of this structure that I have above, the height of the handle is properly calculated. However, if I put it in the structure below (very simplified version trying to represent my app), I get no handle. With some randomly-found examples on the internet I was not able to fix this problem by styling: sometimes I get to see the handle, but it is non-responsive or only small part of it is responsive, in other examples I still have no handle. I do not understand what is the source of problem. I understand that the height is calculated automatically from the list view height. But here list view is given specific height, so the automatic calculation should not be the issue? Which other widget is influencing the scroll bar calculation and should be modified?
Hope it is ok to post example in PySide, because the issue seem to come from underlying structure of Qt widgets themselves.
import sys import os from PySide2 import QtCore from PySide2.QtGui import QPixmap, QIcon, QStandardItemModel, QStandardItem from PySide2.QtWidgets import ( QApplication, QWidget, QVBoxLayout, QListView, QTabWidget, QSizePolicy, ) from PySide2.QtCore import Qt, QDir, QSize class Example(QWidget): def __init__(self): super().__init__() self.layout = QVBoxLayout(self) # File list view setup self.file_list_view = QListView(self) self.file_list_view.setFixedHeight(200) self.layout.addWidget(self.file_list_view) # File model self.file_model = QStandardItemModel(self) self.file_list_view.setModel(self.file_model) def populate_directory_view(self, dir_path): self.file_model.clear() self.dir_path = str(dir_path) # Use os.listdir to get the file names (instead of QDir) files = os.listdir(self.dir_path) for file in files: file_item = QStandardItem(file) file_item.setTextAlignment(Qt.AlignCenter) # Center the text file_item.setEditable(False) self.file_model.appendRow(file_item) # Set the view mode and remove icons self.file_list_view.setViewMode(QListView.ListMode) self.file_list_view.setIconSize(QSize(0, 0)) def reset(self): self.file_model.clear() self.dir_path = "" class ViewerPanel(QWidget): def __init__(self, main_ui): super().__init__() layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.viewer_tabs = QTabWidget() self.viewer_tabs.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.viewer_tabs.setStyleSheet( "background-color: rgb(250,250,250); color: black; padding: 10px;" ) self.viewer = Example() test_directory = R"A:\IP-179_fix_mosaic_processor\trimble\data\pack2\mosaic\output\panos" # Replace with your own test directory path self.viewer.populate_directory_view(test_directory) self.viewer_tabs.addTab(self.viewer, "Viewer") layout.addWidget(self.viewer_tabs) self.setLayout(layout) class MainUI(QWidget): def __init__(self): super().__init__() self.setWindowTitle("Example") self.setWindowState(QtCore.Qt.WindowMaximized) self.setStyleSheet("background-color: rgb(210, 210, 210);") self.setMinimumSize(400, 800) main_layout = QVBoxLayout() main_layout.setContentsMargins(5, 5, 5, 5) right_layout = QVBoxLayout() self.viewer_panel = ViewerPanel(self) right_layout.addWidget(self.viewer_panel) main_layout.addLayout(right_layout) self.setLayout(main_layout) if __name__ == "__main__": app = QApplication(sys.argv) app.setStyle("Fusion") viewer = MainUI() viewer.show() sys.exit(app.exec_())
-
So, by pure random trial-and-error I realized that removing
self.viewer_tabs.setStyleSheet( "background-color: rgb(250,250,250); color: black; padding: 10px;" )
makes my handle visible. Honestly, I fail to see how that can be even remotely related, and still would be grateful for some answer explaining that. I also still want to be able to set style of viewer tabs...
@sapvi said in Vertical QScrollBar seems to have height 0:
Honestly, I fail to see how that can be even remotely related
Stylesheet resets the config / geometry of your bar... for most stylesheets you have to set all if you change one property.
Try to set only the color without the padding... then it might work even right now. Otherwise you have to specifiy the width and height also in stylesheet -
I cannot seem to fix it or even understand why this is happening. I have a list view with its vertical scrollbar. For some reason, handle of my sidebar just does not exist. If I have the list view outside of this structure that I have above, the height of the handle is properly calculated. However, if I put it in the structure below (very simplified version trying to represent my app), I get no handle. With some randomly-found examples on the internet I was not able to fix this problem by styling: sometimes I get to see the handle, but it is non-responsive or only small part of it is responsive, in other examples I still have no handle. I do not understand what is the source of problem. I understand that the height is calculated automatically from the list view height. But here list view is given specific height, so the automatic calculation should not be the issue? Which other widget is influencing the scroll bar calculation and should be modified?
Hope it is ok to post example in PySide, because the issue seem to come from underlying structure of Qt widgets themselves.
import sys import os from PySide2 import QtCore from PySide2.QtGui import QPixmap, QIcon, QStandardItemModel, QStandardItem from PySide2.QtWidgets import ( QApplication, QWidget, QVBoxLayout, QListView, QTabWidget, QSizePolicy, ) from PySide2.QtCore import Qt, QDir, QSize class Example(QWidget): def __init__(self): super().__init__() self.layout = QVBoxLayout(self) # File list view setup self.file_list_view = QListView(self) self.file_list_view.setFixedHeight(200) self.layout.addWidget(self.file_list_view) # File model self.file_model = QStandardItemModel(self) self.file_list_view.setModel(self.file_model) def populate_directory_view(self, dir_path): self.file_model.clear() self.dir_path = str(dir_path) # Use os.listdir to get the file names (instead of QDir) files = os.listdir(self.dir_path) for file in files: file_item = QStandardItem(file) file_item.setTextAlignment(Qt.AlignCenter) # Center the text file_item.setEditable(False) self.file_model.appendRow(file_item) # Set the view mode and remove icons self.file_list_view.setViewMode(QListView.ListMode) self.file_list_view.setIconSize(QSize(0, 0)) def reset(self): self.file_model.clear() self.dir_path = "" class ViewerPanel(QWidget): def __init__(self, main_ui): super().__init__() layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.viewer_tabs = QTabWidget() self.viewer_tabs.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.viewer_tabs.setStyleSheet( "background-color: rgb(250,250,250); color: black; padding: 10px;" ) self.viewer = Example() test_directory = R"A:\IP-179_fix_mosaic_processor\trimble\data\pack2\mosaic\output\panos" # Replace with your own test directory path self.viewer.populate_directory_view(test_directory) self.viewer_tabs.addTab(self.viewer, "Viewer") layout.addWidget(self.viewer_tabs) self.setLayout(layout) class MainUI(QWidget): def __init__(self): super().__init__() self.setWindowTitle("Example") self.setWindowState(QtCore.Qt.WindowMaximized) self.setStyleSheet("background-color: rgb(210, 210, 210);") self.setMinimumSize(400, 800) main_layout = QVBoxLayout() main_layout.setContentsMargins(5, 5, 5, 5) right_layout = QVBoxLayout() self.viewer_panel = ViewerPanel(self) right_layout.addWidget(self.viewer_panel) main_layout.addLayout(right_layout) self.setLayout(main_layout) if __name__ == "__main__": app = QApplication(sys.argv) app.setStyle("Fusion") viewer = MainUI() viewer.show() sys.exit(app.exec_())
-
@sapvi said in Vertical QScrollBar seems to have height 0:
For some reason, handle of my sidebar just does not exist.
The handle / scrollbar only appears when needed.
Try to set vertical scrollBar policy to
Qt::ScrollBarAlwaysOn
@Pl45m4 well, of course we are talking about the case where it is needed... :) Otherwise there would be no point in the question, and otherwise I would not mention that it appears normally when it is not inside this stricture of layouts & widgets. I have multiple items in the list view, and I can scroll from them with mouse wheel or with the arrows, but the handle is not appearing.
I wanted to edit the example but it seems to be a bit late :/ I changed it to just put there 100 lines hard-coded.
import sys import os from PySide2 import QtCore from PySide2.QtGui import QPixmap, QIcon, QStandardItemModel, QStandardItem from PySide2.QtWidgets import ( QApplication, QWidget, QVBoxLayout, QListView, QTabWidget, QSizePolicy, ) from PySide2.QtCore import Qt, QDir, QSize class Example(QWidget): def __init__(self): super().__init__() self.layout = QVBoxLayout(self) # File list view setup self.file_list_view = QListView(self) self.file_list_view.setFixedHeight(200) self.layout.addWidget(self.file_list_view) # File model self.file_model = QStandardItemModel(self) self.file_list_view.setModel(self.file_model) def populate_directory_view(self): self.file_model.clear() files = ["example_file_path"] * 100 for file in files: file_item = QStandardItem(file) file_item.setTextAlignment(Qt.AlignCenter) # Center the text file_item.setEditable(False) self.file_model.appendRow(file_item) self.file_list_view.setViewMode(QListView.ListMode) self.file_list_view.setIconSize(QSize(0, 0)) def reset(self): self.file_model.clear() class ViewerPanel(QWidget): def __init__(self, main_ui): super().__init__() layout = QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.viewer_tabs = QTabWidget() self.viewer_tabs.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.viewer_tabs.setStyleSheet( "background-color: rgb(250,250,250); color: black; padding: 10px;" ) self.viewer = Example() self.viewer.populate_directory_view() self.viewer_tabs.addTab(self.viewer, "Viewer") layout.addWidget(self.viewer_tabs) self.setLayout(layout) class MainUI(QWidget): def __init__(self): super().__init__() self.setWindowTitle("Example") self.setWindowState(QtCore.Qt.WindowMaximized) self.setStyleSheet("background-color: rgb(210, 210, 210);") self.setMinimumSize(400, 800) main_layout = QVBoxLayout() main_layout.setContentsMargins(5, 5, 5, 5) right_layout = QVBoxLayout() self.viewer_panel = ViewerPanel(self) right_layout.addWidget(self.viewer_panel) main_layout.addLayout(right_layout) self.setLayout(main_layout) if __name__ == "__main__": app = QApplication(sys.argv) app.setStyle("Fusion") viewer = MainUI() viewer.show() sys.exit(app.exec_())
-
So, by pure random trial-and-error I realized that removing
self.viewer_tabs.setStyleSheet( "background-color: rgb(250,250,250); color: black; padding: 10px;" )
makes my handle visible. Honestly, I fail to see how that can be even remotely related, and still would be grateful for some answer explaining that. I also still want to be able to set style of viewer tabs...
-
So, by pure random trial-and-error I realized that removing
self.viewer_tabs.setStyleSheet( "background-color: rgb(250,250,250); color: black; padding: 10px;" )
makes my handle visible. Honestly, I fail to see how that can be even remotely related, and still would be grateful for some answer explaining that. I also still want to be able to set style of viewer tabs...
@sapvi said in Vertical QScrollBar seems to have height 0:
Honestly, I fail to see how that can be even remotely related
Stylesheet resets the config / geometry of your bar... for most stylesheets you have to set all if you change one property.
Try to set only the color without the padding... then it might work even right now. Otherwise you have to specifiy the width and height also in stylesheet -
@sapvi said in Vertical QScrollBar seems to have height 0:
Honestly, I fail to see how that can be even remotely related
Stylesheet resets the config / geometry of your bar... for most stylesheets you have to set all if you change one property.
Try to set only the color without the padding... then it might work even right now. Otherwise you have to specifiy the width and height also in stylesheet@Pl45m4 thank you. Interesting. Not sure how to specify width/height if it is supposed to be extending, so will try without padding.
Is there any explanation why this is happening? Not like it matters for the practical usage, but just curious to read about it more. -