PyQt5 - Make all QScrollArea scrollable
-
I'm have an horizontal
QScrollAreaand i want that even if you're not hovering the scrollbar, just being hover theQScrollAreayou could scroll. -
import sys from PyQt5.QtWidgets import ( QApplication, QLabel, QDialog, QVBoxLayout, QWidget, QGridLayout, QMainWindow, QScrollArea, qApp) from PyQt5.QtCore import Qt class ScrolLabel(QScrollArea): # constructor def __init__(self, *args, **kwargs): QScrollArea.__init__(self, *args, **kwargs) self.setWidgetResizable(True) content = QWidget(self) self.setWidget(content) lay = QVBoxLayout(content) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.label = QLabel(content) self.label.setAlignment(Qt.AlignLeft | Qt.AlignTop) lay.addWidget(self.label) def setText(self, text): self.label.setText(text) class MainWindow(QDialog): def __init__(self): super().__init__() self.layout = QGridLayout(self) scrollable = ScrolLabel() scrollable.setText(r"sO+Yu_b>P*vG1F3W@X\hU/J]o=HaE4M2&9f6m\"j0r<z:e!DlL}q^8[R7y'5~t#k)w(gN-A|B{V,pC.Z$I?K;cSxTdQ`i%n") scrollable.setFixedHeight(60) self.layout.addWidget(scrollable) if __name__ == '__main__': app = QApplication(sys.argv) mainwindow = MainWindow() mainwindow.show() sys.exit(app.exec_())@Patitotective A possible solution is to use an eventFilter to send the QLabel's wheel event to the horizontal QScrollBar:
import sys from PyQt5.QtWidgets import ( QApplication, QLabel, QDialog, QVBoxLayout, QGridLayout, QScrollArea, ) from PyQt5.QtCore import QCoreApplication, QEvent, Qt class ScrolLabel(QScrollArea): # constructor def __init__(self, *args, **kwargs): QScrollArea.__init__(self, *args, **kwargs) self.label = QLabel() self.label.setContentsMargins(0, 10, 0, self.horizontalScrollBar().height()) self.setWidgetResizable(True) self.setWidget(self.label) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.label.installEventFilter(self) def setText(self, text): self.label.setText(text) self.setFixedHeight(self.sizeHint().height()) def eventFilter(self, obj, event): if self.label is obj and event.type() == QEvent.Wheel: QCoreApplication.sendEvent(self.horizontalScrollBar(), event) return super().eventFilter(obj, event) class MainWindow(QDialog): def __init__(self): super().__init__() self.layout = QGridLayout(self) scrollable = ScrolLabel() scrollable.setText( r"sO+Yu_b>P*vG1F3W@X\hU/J]o=HaE4M2&9f6m\"j0r<z:e!DlL}q^8[R7y'5~t#k)w(gN-A|B{V,pC.Z$I?K;cSxTdQ`i%n" ) self.layout.addWidget(scrollable) if __name__ == "__main__": app = QApplication(sys.argv) mainwindow = MainWindow() mainwindow.show() sys.exit(app.exec_()) -
Hi,
Are you using the mouse wheel ?
-
@SGaist If you mean i use the mouse wheel to scroll, yes i do.
Look this video, i try to scroll in the label but it doesn't work.
https://youtu.be/zA1OObSaggA -
@SGaist If you mean i use the mouse wheel to scroll, yes i do.
Look this video, i try to scroll in the label but it doesn't work.
https://youtu.be/zA1OObSaggA@Patitotective please provide a minimal and verifiable example
-
@Patitotective please provide a minimal and verifiable example
import sys from PyQt5.QtWidgets import ( QApplication, QLabel, QDialog, QVBoxLayout, QWidget, QGridLayout, QMainWindow, QScrollArea, qApp) from PyQt5.QtCore import Qt class ScrolLabel(QScrollArea): # constructor def __init__(self, *args, **kwargs): QScrollArea.__init__(self, *args, **kwargs) self.setWidgetResizable(True) content = QWidget(self) self.setWidget(content) lay = QVBoxLayout(content) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.label = QLabel(content) self.label.setAlignment(Qt.AlignLeft | Qt.AlignTop) lay.addWidget(self.label) def setText(self, text): self.label.setText(text) class MainWindow(QDialog): def __init__(self): super().__init__() self.layout = QGridLayout(self) scrollable = ScrolLabel() scrollable.setText(r"sO+Yu_b>P*vG1F3W@X\hU/J]o=HaE4M2&9f6m\"j0r<z:e!DlL}q^8[R7y'5~t#k)w(gN-A|B{V,pC.Z$I?K;cSxTdQ`i%n") scrollable.setFixedHeight(60) self.layout.addWidget(scrollable) if __name__ == '__main__': app = QApplication(sys.argv) mainwindow = MainWindow() mainwindow.show() sys.exit(app.exec_()) -
import sys from PyQt5.QtWidgets import ( QApplication, QLabel, QDialog, QVBoxLayout, QWidget, QGridLayout, QMainWindow, QScrollArea, qApp) from PyQt5.QtCore import Qt class ScrolLabel(QScrollArea): # constructor def __init__(self, *args, **kwargs): QScrollArea.__init__(self, *args, **kwargs) self.setWidgetResizable(True) content = QWidget(self) self.setWidget(content) lay = QVBoxLayout(content) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.label = QLabel(content) self.label.setAlignment(Qt.AlignLeft | Qt.AlignTop) lay.addWidget(self.label) def setText(self, text): self.label.setText(text) class MainWindow(QDialog): def __init__(self): super().__init__() self.layout = QGridLayout(self) scrollable = ScrolLabel() scrollable.setText(r"sO+Yu_b>P*vG1F3W@X\hU/J]o=HaE4M2&9f6m\"j0r<z:e!DlL}q^8[R7y'5~t#k)w(gN-A|B{V,pC.Z$I?K;cSxTdQ`i%n") scrollable.setFixedHeight(60) self.layout.addWidget(scrollable) if __name__ == '__main__': app = QApplication(sys.argv) mainwindow = MainWindow() mainwindow.show() sys.exit(app.exec_())@Patitotective A possible solution is to use an eventFilter to send the QLabel's wheel event to the horizontal QScrollBar:
import sys from PyQt5.QtWidgets import ( QApplication, QLabel, QDialog, QVBoxLayout, QGridLayout, QScrollArea, ) from PyQt5.QtCore import QCoreApplication, QEvent, Qt class ScrolLabel(QScrollArea): # constructor def __init__(self, *args, **kwargs): QScrollArea.__init__(self, *args, **kwargs) self.label = QLabel() self.label.setContentsMargins(0, 10, 0, self.horizontalScrollBar().height()) self.setWidgetResizable(True) self.setWidget(self.label) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.label.installEventFilter(self) def setText(self, text): self.label.setText(text) self.setFixedHeight(self.sizeHint().height()) def eventFilter(self, obj, event): if self.label is obj and event.type() == QEvent.Wheel: QCoreApplication.sendEvent(self.horizontalScrollBar(), event) return super().eventFilter(obj, event) class MainWindow(QDialog): def __init__(self): super().__init__() self.layout = QGridLayout(self) scrollable = ScrolLabel() scrollable.setText( r"sO+Yu_b>P*vG1F3W@X\hU/J]o=HaE4M2&9f6m\"j0r<z:e!DlL}q^8[R7y'5~t#k)w(gN-A|B{V,pC.Z$I?K;cSxTdQ`i%n" ) self.layout.addWidget(scrollable) if __name__ == "__main__": app = QApplication(sys.argv) mainwindow = MainWindow() mainwindow.show() sys.exit(app.exec_()) -
@Patitotective A possible solution is to use an eventFilter to send the QLabel's wheel event to the horizontal QScrollBar:
import sys from PyQt5.QtWidgets import ( QApplication, QLabel, QDialog, QVBoxLayout, QGridLayout, QScrollArea, ) from PyQt5.QtCore import QCoreApplication, QEvent, Qt class ScrolLabel(QScrollArea): # constructor def __init__(self, *args, **kwargs): QScrollArea.__init__(self, *args, **kwargs) self.label = QLabel() self.label.setContentsMargins(0, 10, 0, self.horizontalScrollBar().height()) self.setWidgetResizable(True) self.setWidget(self.label) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAsNeeded) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.label.installEventFilter(self) def setText(self, text): self.label.setText(text) self.setFixedHeight(self.sizeHint().height()) def eventFilter(self, obj, event): if self.label is obj and event.type() == QEvent.Wheel: QCoreApplication.sendEvent(self.horizontalScrollBar(), event) return super().eventFilter(obj, event) class MainWindow(QDialog): def __init__(self): super().__init__() self.layout = QGridLayout(self) scrollable = ScrolLabel() scrollable.setText( r"sO+Yu_b>P*vG1F3W@X\hU/J]o=HaE4M2&9f6m\"j0r<z:e!DlL}q^8[R7y'5~t#k)w(gN-A|B{V,pC.Z$I?K;cSxTdQ`i%n" ) self.layout.addWidget(scrollable) if __name__ == "__main__": app = QApplication(sys.argv) mainwindow = MainWindow() mainwindow.show() sys.exit(app.exec_())@eyllanesc Thanks, it worked.