Add page switch feature to main window and now all qt stylesheet are loaded from an external file.

Rename test dialog window to test page.
This commit is contained in:
wei
2026-07-14 16:41:14 +08:00
parent 1c6438040c
commit e15bd758f3
10 changed files with 322 additions and 55 deletions
+166 -43
View File
@@ -1,15 +1,84 @@
import logging
from pathlib import Path
from typing import Callable
from PySide6.QtGui import QIcon, Qt, QImage, QPixmap
from PySide6.QtWidgets import QApplication, QMainWindow, QLabel, QVBoxLayout, QWidget, QPushButton
from PySide6 import QtWidgets
from PySide6.QtCore import QSize
from PySide6.QtGui import QIcon, Qt, QPixmap
from PySide6.QtWidgets import QApplication, QMainWindow, QLabel, QVBoxLayout, QWidget, QPushButton, QStyle, QToolButton, \
QStackedWidget
from core_lib.qt.hack import move_window_to_center
from dialog.test import TestDialog
from core_lib.qt.hack import move_window_to_center, recolor_standard_icon
from core_lib.qt import messagebox
from pages.test import TestPage
LAUNCHER_VERSION = "alpha_0.0.1"
MAIN_REPO_URL = "https://repo.weispace.net/wei/Launcher/"
class ToolBar(QtWidgets.QToolBar):
def __init__(self, app: QApplication, parent=None):
super(ToolBar, self).__init__(parent)
self.app = app
self.orientationChanged.connect(self._update_widget_size)
def _update_widget_size(self, orientation):
vertical = orientation == Qt.Orientation.Vertical
for button in self.findChildren(QToolButton):
if vertical:
button.setToolButtonStyle(
Qt.ToolButtonStyle.ToolButtonIconOnly
)
button.setFixedSize(60, 60)
continue
button.setMinimumSize(0, 0)
button.setMaximumSize(16777215, 16777215)
if not button.icon().isNull() and not button.text():
button.setToolButtonStyle(
Qt.ToolButtonStyle.ToolButtonIconOnly
)
button.setFixedSize(60, 60)
elif button.icon().isNull():
button.setToolButtonStyle(
Qt.ToolButtonStyle.ToolButtonTextOnly
)
button.setFixedWidth(150)
else:
button.setToolButtonStyle(
Qt.ToolButtonStyle.ToolButtonTextBesideIcon
)
button.setFixedWidth(150)
def add_button(self, text=None, icon: QIcon=None) -> QToolButton:
button = QtWidgets.QToolButton(self)
if text:
text = " "+text
button.setText(text)
if icon:
button.setIcon(icon)
button.setIconSize(QSize(32, 32))
if text:
button.setToolButtonStyle(
Qt.ToolButtonStyle.ToolButtonTextBesideIcon
)
else:
button.setToolButtonStyle(
Qt.ToolButtonStyle.ToolButtonIconOnly
)
button.setAutoRaise(True)
return button
def update_all(self):
self._update_widget_size(self.orientation())
self.update()
class Launcher(QApplication):
def __init__(self):
super().__init__()
@@ -26,16 +95,15 @@ class Launcher(QApplication):
self.program_dir = Path(__file__).parent
self.work_dir = Path.cwd()
# test page
self.test_dialog = TestDialog(self, self.main_window)
# Set icon
if self.icon_path.exists():
self.setWindowIcon(QIcon(self.icon_path.as_posix()))
else:
self.logger.error("No icon found.")
self.central = QWidget()
# Main layout
self.central = QStackedWidget()
self.toolbar = ToolBar(self, self.main_window)
# center message (will be deleted if launcher finished development)
content = """Still digging!"""
@@ -51,7 +119,6 @@ class Launcher(QApplication):
self.repo_url_label = QLabel(f"<a href=\"{MAIN_REPO_URL}\">Main repo</a>")
self.repo_url_label.setObjectName("repo_url_label")
self.repo_url_label.setOpenExternalLinks(True)
self.main_layout = QVBoxLayout(self.central)
if Path(self.resources_dir, "pictures", "in_progress.png").exists():
image = QPixmap(Path(self.resources_dir, "pictures", "in_progress.png"))
@@ -59,49 +126,71 @@ class Launcher(QApplication):
else:
self.icon_label.setText("Ouch. The icon is missing.")
self.open_test_window = QPushButton("Open test")
self.open_test_window.clicked.connect(lambda : self.test_dialog.show())
self.open_test_window.setObjectName("open_test_window")
# Homepage
self.home_page = QWidget()
self.home_layout = QVBoxLayout(self.home_page)
self.home_layout.addStretch()
self.home_layout.addWidget(self.icon_label, alignment=Qt.AlignmentFlag.AlignCenter)
self.home_layout.addWidget(self.dev_info_box, alignment=Qt.AlignmentFlag.AlignHCenter)
self.home_layout.addWidget(self.dev_info_2, alignment=Qt.AlignmentFlag.AlignHCenter)
self.home_layout.addWidget(self.version_label, alignment=Qt.AlignmentFlag.AlignHCenter)
self.home_layout.addWidget(self.repo_url_label, alignment=Qt.AlignmentFlag.AlignHCenter)
self.home_layout.addStretch()
self.main_layout.addStretch()
self.main_layout.addWidget(self.icon_label, alignment=Qt.AlignmentFlag.AlignCenter)
self.main_layout.addWidget(self.dev_info_box, alignment=Qt.AlignmentFlag.AlignHCenter)
self.main_layout.addWidget(self.dev_info_2, alignment=Qt.AlignmentFlag.AlignHCenter)
self.main_layout.addWidget(self.version_label, alignment=Qt.AlignmentFlag.AlignHCenter)
self.main_layout.addWidget(self.repo_url_label, alignment=Qt.AlignmentFlag.AlignHCenter)
self.main_layout.addStretch()
self.main_layout.addWidget(self.open_test_window, alignment=Qt.AlignmentFlag.AlignRight)
# test page
self.test_page = TestPage(self, self.main_window)
# Add page
self.central.addWidget(self.home_page)
self.central.addWidget(self.test_page)
# Bind toolbar and center widget
self.main_window.addToolBar(Qt.ToolBarArea.LeftToolBarArea, self.toolbar)
self.main_window.setCentralWidget(self.central)
self.setStyleSheet("""
QLabel#dev_info_box {
font-size: 20pt;
font-weight: bold;
}
QLabel#dev_info_message {
font-size: 10pt;
}
QLabel#version_label, QLabel#version_label {
font-weight: bold;
}
QLabel#icon_label {
border-radius: 20px;
}
QPushButton#open_test_window {
padding: 10px;
}
""")
# Apply qss
self.apply_qss(Path("main.qss"), self.setStyleSheet)
self.apply_qss(Path("toolbar.qss"), self.toolbar.setStyleSheet)
# Toolbar
# Test Window btn
self.open_test_page = self.toolbar.add_button(" Tests", icon=QIcon(Path(self.icon_dir, "debug.png").as_posix()))
self.open_test_page.setObjectName("open_test_page")
# Home btn
self.home_button = self.toolbar.add_button(icon=QIcon(Path(self.icon_dir, "home.png").as_posix()))
self.home_button.clicked.connect(
lambda: self.central.setCurrentWidget(self.home_page)
)
# Bind tool buttons
self.toolbar.addWidget(self.home_button)
self.toolbar.addSeparator()
self.toolbar.addWidget(self.open_test_page)
self.toolbar.setMovable(True)
self.toolbar.setFloatable(False)
self.toolbar.setAllowedAreas(Qt.ToolBarArea.AllToolBarAreas)
self.home_button.clicked.connect(
lambda: self.set_current_page(self.home_page, self.home_button)
)
self.open_test_page.clicked.connect(
lambda: self.set_current_page(self.test_page, self.open_test_page)
)
self.set_current_page(self.home_page, self.home_button)
def exec(self):
self.main_window.show()
self.test_dialog.show()
self.toolbar.update_all()
self.exec_()
def set_current_page(self, page: QWidget, related_button: QToolButton):
self.central.setCurrentWidget(page)
related_button.setFocus()
@property
def temp_dir(self):
return self.work_dir / "temp"
@@ -126,6 +215,40 @@ class Launcher(QApplication):
def icon_path(self):
return self.resources_dir / "icons" / "icon.png"
@property
def icon_dir(self):
return self.resources_dir / "icons"
@property
def launcher_version(self):
return LAUNCHER_VERSION
@property
def styles_path(self):
return self.resources_dir / "styles"
def apply_qss(self, qss_relative_path: Path, apply_qss_callback: Callable[[str], None]) -> str:
full_path = self.styles_path / qss_relative_path
if not full_path.exists():
messagebox.error(
self.main_window,
"Resource Error",
"Missing stylesheet file: {}".format(full_path),
)
return ""
try:
data = full_path.read_text()
apply_qss_callback(data)
except Exception as e:
messagebox.error(
self.main_window,
"Resource Error",
"Unable to apply QSS stylesheet {}: {}".format(full_path, e),
)
return ""