From 3f9cc45f3c40a3ce6d4ceb86745a0ea05b96a615 Mon Sep 17 00:00:00 2001 From: Qing Date: Mon, 16 Dec 2024 00:12:15 -0500 Subject: [PATCH 1/2] - New: 1.Using dynamic font size for lables of GUI by the scaling DPI of the screen. 2. New option in Theme menue to set the font size of the GUI. --- Docs/ChangeLog.md | 5 ++ metax/gui/main_gui.py | 135 +++++++++++++++++++++------- metax/taxafunc_ploter/basic_plot.py | 2 +- metax/utils/version.py | 2 +- pyproject.toml | 2 +- 5 files changed, 110 insertions(+), 36 deletions(-) diff --git a/Docs/ChangeLog.md b/Docs/ChangeLog.md index 9adee17..ff4cb3b 100644 --- a/Docs/ChangeLog.md +++ b/Docs/ChangeLog.md @@ -1,3 +1,8 @@ +# Version: 1.120.0 +## Date: 2024-12-15 +### Changes: +- New: 1.Using dynamic font size for lables of GUI by the scaling DPI of the screen. 2. New option in Theme menue to set the font size of the GUI. + # Version: 1.119.11 ## Date: 2024-12-10 ### Changes: diff --git a/metax/gui/main_gui.py b/metax/gui/main_gui.py index 3ef8125..af10909 100644 --- a/metax/gui/main_gui.py +++ b/metax/gui/main_gui.py @@ -161,6 +161,8 @@ def __init__(self, MainWindow): self.MainWindow.resize(1200, 800) self.MainWindow.setWindowTitle("MetaX v" + __version__) + self.font_size = 12 + self.current_theme = 'light_blue' self.logger = LoggerManager() @@ -261,7 +263,7 @@ def __init__(self, MainWindow): self.actionCheck_Update.triggered.connect(lambda: self.check_update(show_message=True, manual_check_trigger=True)) self.actionSettings.triggered.connect(self.show_settings_window) - self.screen = self.screen = QApplication.screenAt(QCursor.pos()).geometry() + self.screen = QApplication.screenAt(QCursor.pos()).geometry() self.screen_width = self.screen.width() self.screen_height = self.screen.height() @@ -922,37 +924,81 @@ def hide_plot_setting_groupbox(self): ############### basic function End ############### - - - + def init_theme_menu(self): # Create a menu for themes theme_menu = QMenu("Themes", self.MainWindow) # Fetch all available themes themes = list_themes() - # replace the .xml suffix + # Replace the .xml suffix themes = [theme.replace('.xml', '') for theme in themes] - # reordering the themes , light theme first + # Reorder the themes, light themes first light_themes = [theme for theme in themes if "light_" in theme] dark_themes = [theme for theme in themes if "dark_" in theme] themes = light_themes + dark_themes + # Add themes to the menu for theme in themes: theme_action = QAction(theme, self.MainWindow) - theme_action.triggered.connect(lambda checked, theme=theme: self.change_theme(theme)) + theme_action.triggered.connect(lambda checked, theme=theme: self.change_theme(theme, silent=False, is_load_font_size_from_settings=False)) theme_menu.addAction(theme_action) - # Add theme menu to menu bar + # Add a font size submenu + font_size_menu = QMenu("Font Size", self.MainWindow) + + # Predefined font size options + predefined_sizes = [10, 12, 14, 16, 18, 20] + + for size in predefined_sizes: + size_action = QAction(f"{size} pt", self.MainWindow) + size_action.triggered.connect(lambda checked, size=size: self.set_font_size(size)) + font_size_menu.addAction(size_action) + + # Add an option for custom font size + custom_size_action = QAction("Custom...", self.MainWindow) + custom_size_action.triggered.connect(self.set_custom_font_size) + font_size_menu.addAction(custom_size_action) + + # Add the font size menu to the theme menu + theme_menu.addMenu(font_size_menu) + + # Add theme menu to the menu bar self.MainWindow.menuBar().addMenu(theme_menu) + + def set_font_size(self, size): + """ + Set the font size and apply the current theme. + """ + self.font_size = size + self.change_theme(self.current_theme, silent=False, is_load_font_size_from_settings=False) + + def set_custom_font_size(self): + """ + Open a dialog for the user to input a custom font size. + """ + from PyQt5.QtWidgets import QInputDialog + + size, ok = QInputDialog.getInt( + self.MainWindow, + "Custom Font Size", + "Enter font size (pt):", + value=self.font_size, + min=8, + max=72 + ) + if ok: + self.set_font_size(size) + def init_theme(self): if self.settings.contains("theme"): theme = self.settings.value("theme", type=str) - print(f"Loading theme {theme}...") + theme = theme if theme != "" else "light_blue" else: theme = "light_blue" print(f"Loading default theme {theme}...") + self.current_theme = theme self.change_theme(theme, silent=True) # restore the window size @@ -967,11 +1013,13 @@ def init_theme(self): - def change_theme(self, theme, silent=False): + def change_theme(self, theme, silent=False, is_load_font_size_from_settings=True): if not silent: - self.show_message(f"Changing theme to {theme}...") + text = f"Changing...\n\nTheme: {theme}\nFont size: {self.font_size}" + self.show_message(text) # save the theme to settings self.settings.setValue("theme", theme) + self.current_theme = theme #! Deprecated, switch to manual change in Settings ## save the theme mode to GUI attribute (dark or light) @@ -1000,8 +1048,22 @@ def change_theme(self, theme, silent=False): combobox = getattr(self, attribute_name) combobox.clear() ############### avoid the window size change when change theme ############### - - + if is_load_font_size_from_settings: + screen = QApplication.screenAt(QCursor.pos()) + logical_dpi = screen.logicalDotsPerInch() + scaling_factor = logical_dpi / 96.0 + # read if setting has font size and height + if self.settings.contains("font_size"): + self.font_size = self.settings.value("font_size", type=int) + print(f"Reading font size from settings file: {self.font_size}") + else: + self.font_size = int(12 * scaling_factor) + print(f"Setting default font size: {self.font_size}") + + + font_size = self.font_size + height = self.font_size + 8 + custom_css = ''' QGroupBox {{ text-transform: none; @@ -1017,36 +1079,36 @@ def change_theme(self, theme, silent=False): text-transform: none; }} QLineEdit {{ - font-size: 12px; + font-size: setted_font_size; }} QLabel {{ - font-size: 12px; + font-size: setted_font_size; }} QComboBox {{ - font-size: 12px; - height: 20px; + font-size: setted_font_size; + height: setted_height; }} QSpinBox {{ - font-size: 12px; - height: 20px; + font-size: setted_font_size; + height: setted_height; }} QListWidget {{ - font-size: 12px; + font-size: setted_font_size; }} QDoubleSpinBox {{ - font-size: 12px; - height: 20px; + font-size: setted_font_size; + height: setted_height; }} QCheckBox {{ - font-size: 12px; - height: 20px; + font-size: setted_font_size; + height: setted_height; }} QRadioButton {{ - font-size: 12px; - height: 20px; + font-size: setted_font_size; + height: setted_height; }} QToolBox {{ - font-size: 12px; + font-size: setted_font_size; font-weight: bold; }} QPushButton {{ @@ -1055,13 +1117,13 @@ def change_theme(self, theme, silent=False): background-color: {QTMATERIAL_SECONDARYCOLOR}; border: 1px solid {QTMATERIAL_PRIMARYCOLOR}; border-radius: 2px; - font-size: 12px; + font-size: setted_font_size; padding: 5px; margin: 2px; - height: 20px; + height: setted_height; }} - - ''' + + '''.replace('setted_font_size', f'{font_size}px').replace('setted_height', f'{height}px') current_app = QtWidgets.QApplication.instance() extra = { @@ -1288,6 +1350,9 @@ def save_basic_settings(self, line_edit_name: str | None = None): # save current window size self.settings.setValue("window_size", self.MainWindow.size()) + + # save font_size + self.settings.setValue("font_size", self.font_size) def save_set_multi_table_settings(self): @@ -1519,8 +1584,9 @@ def closeEvent(self, event): msgBox.addButton(do_not_close_button, QMessageBox.RejectRole) reply = msgBox.exec() - if reply == 0 or reply == 1: + if reply == 0 or reply == 1: # 0 is save and close, 1 is close without saving try: + if reply == 0: self.show_message("Saving settings...", "Closing...") if getattr(self, 'tfa', None) is None: @@ -1528,7 +1594,10 @@ def closeEvent(self, event): self.save_basic_settings() else: self.save_metax_obj_to_file(save_path=self.metax_home_path, no_message=True) - + else: # close without saving + # save settings.ini only + self.save_basic_settings() + # 关闭 self.web_list 中的所有窗口 for web_window in self.web_list: web_window.close() diff --git a/metax/taxafunc_ploter/basic_plot.py b/metax/taxafunc_ploter/basic_plot.py index 92ca6ba..1625aaf 100644 --- a/metax/taxafunc_ploter/basic_plot.py +++ b/metax/taxafunc_ploter/basic_plot.py @@ -694,7 +694,7 @@ def plot_upset(self, df, title_name='Table', width=12, height=6, font_size=10, plt.rcParams.update({'font.size': font_size}) upset_plot(upset_data, fig = fig, show_counts=show_label, show_percentages=show_percentages if show_label else False, - element_size=None, sort_categories_by ='input', + element_size=None, sort_categories_by ='-input', min_subset_size=min_subset_size if min_subset_size != 0 else None, max_subset_rank=max_subset_rank if max_subset_rank != 0 else None) diff --git a/metax/utils/version.py b/metax/utils/version.py index 5118493..9d9ce7b 100644 --- a/metax/utils/version.py +++ b/metax/utils/version.py @@ -1,2 +1,2 @@ -__version__ = '1.119.11' +__version__ = '1.120.0' API_version = '4' \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 058dd95..e72cca5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "MetaXTools" -version = "1.119.11" +version = "1.120.0" description = "MetaXTools is a novel tool for linking peptide sequences with taxonomic and functional information in Metaproteomics." readme = "README_PyPi.md" license = { text = "NorthOmics" } From 8b0ddabd48f1a8423a8c9d2da3664e8b881f381f Mon Sep 17 00:00:00 2001 From: Qing <44231502+byemaxx@users.noreply.github.com> Date: Mon, 16 Dec 2024 12:45:01 -0500 Subject: [PATCH 2/2] Fix: 1. font size change was not work for some widgets. 2. some hyperlinks in cookbook were not work. --- .github/workflows/jekyll-gh-pages.yml | 8 ++++++-- Docs/ChangeLog.md | 5 +++++ metax/gui/main_gui.py | 28 +++++++++++++++++++++------ metax/tests/test_metax.py | 11 +++++++++++ metax/utils/version.py | 2 +- pyproject.toml | 2 +- 6 files changed, 46 insertions(+), 10 deletions(-) diff --git a/.github/workflows/jekyll-gh-pages.yml b/.github/workflows/jekyll-gh-pages.yml index a2fbff7..ec25460 100644 --- a/.github/workflows/jekyll-gh-pages.yml +++ b/.github/workflows/jekyll-gh-pages.yml @@ -61,7 +61,7 @@ jobs: for heading in headings: level = len(heading[0]) title = heading[1] - anchor = re.sub(r'\W+', '-', title.lower()).strip('-') + anchor = re.sub(r'[^a-zA-Z0-9]+', '-', title.strip()).lower().strip('-') toc_items.append((level, title, anchor)) # Convert markdown to HTML @@ -71,7 +71,11 @@ jobs: html_content = re.sub(r'', r'
', html_content) html_content = re.sub(r'', r'
', html_content) html_content = re.sub(r'
', r'', html_content) - + html_content = re.sub( + r'href="##([^"]+)"', # 匹配类似 ##Module-4.-Peptide-Annotator 的链接 + lambda match: f'href="#{re.sub(r"[^a-zA-Z0-9]+", "-", match.group(1).strip()).lower().strip("-")}"', + html_content + ) # Jinja2 template for HTML output template = Template(''' diff --git a/Docs/ChangeLog.md b/Docs/ChangeLog.md index ff4cb3b..274cf37 100644 --- a/Docs/ChangeLog.md +++ b/Docs/ChangeLog.md @@ -1,3 +1,8 @@ +# Version: 1.120.1 +## Date: 2024-12-16 +### Changes: +- Fix: font size change was not work for some widgets. + # Version: 1.120.0 ## Date: 2024-12-15 ### Changes: diff --git a/metax/gui/main_gui.py b/metax/gui/main_gui.py index af10909..285d334 100644 --- a/metax/gui/main_gui.py +++ b/metax/gui/main_gui.py @@ -137,7 +137,7 @@ from .metax_gui.ui_lca_help import UiLcaHelpDialog from .metax_gui.ui_func_threshold_help import UifuncHelpDialog from .metax_gui.generic_thread import FunctionExecutor - from .metax.gui.metax_gui.resources import icon_rc + from .metax_gui.resources import icon_rc # noqa: F401 from ..peptide_annotator.metalab2otf import MetaLab2OTF from ..peptide_annotator.peptable_annotator import PeptideAnnotator @@ -1015,7 +1015,7 @@ def init_theme(self): def change_theme(self, theme, silent=False, is_load_font_size_from_settings=True): if not silent: - text = f"Changing...\n\nTheme: {theme}\nFont size: {self.font_size}" + text = f"Changing theme to {theme}...\n\nTheme: {theme}\nFont size: {self.font_size}" self.show_message(text) # save the theme to settings self.settings.setValue("theme", theme) @@ -1122,6 +1122,24 @@ def change_theme(self, theme, silent=False, is_load_font_size_from_settings=True margin: 2px; height: setted_height; }} + QTabBar {{ + font-size: setted_font_size; + }} + QMenuBar {{ + font-size: setted_font_size; + }} + QMenuBar::item {{ + font-size: setted_font_size; + }} + QTextBrowser {{ + font-size: setted_font_size; + }} + QTableWidget {{ + font-size: setted_font_size; + }} + QHeaderView::section {{ + font-size: setted_font_size; + }} '''.replace('setted_font_size', f'{font_size}px').replace('setted_height', f'{height}px') current_app = QtWidgets.QApplication.instance() @@ -1132,10 +1150,10 @@ def change_theme(self, theme, silent=False, is_load_font_size_from_settings=True # Apply the selected theme if "light" in theme: - self.msgbox_style = "QLabel{min-width: 400px; color: black; font-size: 12px;} QMessageBox{background-color: white;}" + self.msgbox_style = "QLabel{min-width: 400px; color: black; font-size: setted_font_size;} QMessageBox{background-color: white;}".replace('setted_font_size', f'{font_size}px') apply_stylesheet(current_app, theme=theme, invert_secondary=True, extra=extra) else: - self.msgbox_style = "QLabel{min-width: 400px; color: white; font-size: 12px;} QMessageBox{background-color: #333;}" + self.msgbox_style = "QLabel{min-width: 400px; color: white; font-size: setted_font_size;} QMessageBox{background-color: #333;}".replace('setted_font_size', f'{font_size}px') # set text color to white of QComboBox , QSpinBox and QDoubleSpinBox , lineEdit custom_css += ''' QComboBox {{ @@ -1820,8 +1838,6 @@ def show_message(self,message,title='Information'): self.msg.setWindowModality(Qt.NonModal) self.msg.setWindowTitle(title) - if not hasattr(self, 'msgbox_style'): - self.msgbox_style = "QLabel{min-width: 400px; color: black; font-size: 12px;} QMessageBox{background-color: white;}" self.msg.setStyleSheet(self.msgbox_style) self.msg.setText(message) diff --git a/metax/tests/test_metax.py b/metax/tests/test_metax.py index e69de29..56e80fb 100644 --- a/metax/tests/test_metax.py +++ b/metax/tests/test_metax.py @@ -0,0 +1,11 @@ +import sys +import os +script_dir = os.path.dirname(__file__) #<-- absolute dir the script is in +parentDir = os.path.abspath(os.path.join(script_dir, os.pardir)) +grandParentDir = os.path.abspath(os.path.join(parentDir, os.pardir)) +sys.path.append(grandParentDir) + + +from metax.gui.main_gui import runGUI + +runGUI() \ No newline at end of file diff --git a/metax/utils/version.py b/metax/utils/version.py index 9d9ce7b..dd68a74 100644 --- a/metax/utils/version.py +++ b/metax/utils/version.py @@ -1,2 +1,2 @@ -__version__ = '1.120.0' +__version__ = '1.120.1' API_version = '4' \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index e72cca5..48287e9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "MetaXTools" -version = "1.120.0" +version = "1.120.1" description = "MetaXTools is a novel tool for linking peptide sequences with taxonomic and functional information in Metaproteomics." readme = "README_PyPi.md" license = { text = "NorthOmics" }