Skip to content

Commit

Permalink
Add NoBorderScrollArea, example and tests (#155)
Browse files Browse the repository at this point in the history
  • Loading branch information
DanicaSTFC authored Aug 7, 2024
1 parent 1a182f7 commit 8d157be
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 2 deletions.
5 changes: 3 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Version x.x.x
- Edit next and prev in UIMultiStepWidget #151
# Version 1.0.1
- Add NoBorderScrollArea, example and tests (#155)
- Edit next and prev in UIMultiStepWidget (#151)
- Remove question mark from form dialog (#150)

# Version 1.0.0
Expand Down
40 changes: 40 additions & 0 deletions eqt/ui/NoBorderScrollArea.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import re

import qdarkstyle
from PySide2.QtWidgets import QPushButton, QScrollArea, QWidget


class NoBorderScrollArea(QScrollArea):
def __init__(self, widget, parent=None):
"""Creates an instance of a QScrollArea and sets its border to none.
Sets its widget to resizable. Due to a bug in `qdarkstyle`, the PushButtons in the
widget do not inherit the right style. The init applies `qdarkstyle` to all the buttons
present in the widget when the object is created. Any button added to the widget after the
init is invoked will not be styled as expected. In this case, the method
`apply_qdarkstyle_to_buttons` would need to be invoked by the user after the object is
instanced."""
super().__init__(parent)
self.setStyleSheet("QScrollArea { border: none; }")
self.setWidgetResizable(True)
self.setWidget(widget)
self.apply_qdarkstyle_to_buttons(widget)

def apply_qdarkstyle_to_buttons(self, widget):
"""Applies the qdarkstyle to all the buttons in the widget explicitly.
This ensures that the style is consistent with the rest of the app."""
if isinstance(widget, QPushButton):

button_style = self._extract_qdarkstyle_button_style()
widget.setStyleSheet(button_style)
for child in widget.findChildren(QWidget):
self.apply_qdarkstyle_to_buttons(child)

def _extract_qdarkstyle_button_style(self):
"""Returns the QPushButton styles from qdarkstyle, including the different
button styles."""
style = qdarkstyle.load_stylesheet(qt_api='pyside2')
pattern = re.compile(r"(QPushButton\s*{[^}]*}|QPushButton\s*:[^}]*{[^}]*})", re.DOTALL)
matches = pattern.findall(style)
if matches:
return ''.join(matches)
return ""
39 changes: 39 additions & 0 deletions examples/NoBorderScrollArea_example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import sys

from PySide2 import QtWidgets
from PySide2.QtWidgets import QPushButton

from eqt.ui.NoBorderScrollArea import NoBorderScrollArea


class MainUI(QtWidgets.QMainWindow):
def __init__(self, parent=None):
"""Any button added after the `NoBorderScrollArea` is instanced will not be styled as
expected, due to the bug in `qdarkstyle`. The method `apply_qdarkstyle_to_buttons` needs
to be invoked."""
QtWidgets.QMainWindow.__init__(self, parent)

layout = QtWidgets.QVBoxLayout()
widg = QtWidgets.QWidget()
widg.setLayout(layout)

layout.addWidget(QPushButton("Test"))
layout.addWidget(QPushButton("Test2"))

self.scroll_area_widget = NoBorderScrollArea(widg)

layout.addWidget(QPushButton("Test3"))
self.scroll_area_widget.apply_qdarkstyle_to_buttons(widg)
layout.addWidget(QPushButton("Test4"))

self.setCentralWidget(self.scroll_area_widget)

self.show()


if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)

window = MainUI()

sys.exit(app.exec_())
26 changes: 26 additions & 0 deletions test/test_NoBorderScrollArea.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import unittest

from PySide2.QtWidgets import QHBoxLayout, QPushButton, QWidget

from eqt.ui.NoBorderScrollArea import NoBorderScrollArea

from . import is_ci, skip

if is_ci:
skip("Running in CI (no GUI)", allow_module_level=True)


class TestNoBorderScrollArea(unittest.TestCase):
def setUp(self):
'''Initialises a NoBorderScrollArea widget and adds it to a layout.'''
self.main_widget = QWidget()
self.layout = QHBoxLayout(self.main_widget)
self.scroll_area_widget = NoBorderScrollArea(QPushButton())
self.layout.addWidget(self.scroll_area_widget)

def test_scroll_area_creation(self):
'''
Tests the init method of the NoBorderScrollArea class.
'''
self.assertIsNotNone(self.scroll_area_widget,
"NoBorderScrollArea widget should be created")

0 comments on commit 8d157be

Please sign in to comment.