From 178ec098ada550a147de4c87f074d731ded0e214 Mon Sep 17 00:00:00 2001 From: falkTX Date: Thu, 24 Jul 2025 21:45:26 +0200 Subject: [PATCH] Make GUI settings panel compatible with PyQt6 or PyQt5 Signed-off-by: falkTX --- README.md | 5 ++- gui/Makefile | 32 +++++++++++++++ gui/settings.py | 20 +++++++--- gui/settings.ui | 7 ++-- gui/ui_settings.py | 98 ++++++++++++++++++---------------------------- 5 files changed, 92 insertions(+), 70 deletions(-) diff --git a/README.md b/README.md index f9be82c..ab01256 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ sudo cp build64/wineasio64.dll.so /usr/lib/x86_64-linux-gnu/wine/x86_64-unix/ For user convenience a `wineasio-register` script is included in this repo, if you are packaging WineASIO consider installing it as part of WineASIO. -Additionally a control panel GUI is provided in this repository's `gui` subdir, which requires PyQt5 to build and run. +Additionally a control panel GUI is provided in this repository's `gui` subdir, which requires PyQt6 or PyQt5 to build and run. The WineASIO driver will use this GUI as the ASIO control panel. ### REGISTERING @@ -123,7 +123,8 @@ that overrides the JACK client name derived from the program name. ### CHANGE LOG -#### 1.3.0 WIP +#### 1.3.0 +* 24-JUL-2025: Make GUI settings panel compatible with PyQt6 or PyQt5 * 17-JUL-2025: Load libjack.so.0 dynamically at runtime, removing build dep * 17-JUL-2025: Remove useless -mnocygwin flag * 28-JUN-2025: Remove dependency on asio headers diff --git a/gui/Makefile b/gui/Makefile index eb24340..c7150d5 100644 --- a/gui/Makefile +++ b/gui/Makefile @@ -16,10 +16,42 @@ all: # --------------------------------------------------------------------------------------------------------------------- # UI code +define UI_IMPORTS +try:\\n + from PyQt6.QtCore import Qt, QCoreApplication, QMetaObject\\n + from PyQt6.QtWidgets import QCheckBox, QComboBox, QDialogButtonBox, QLabel, QGroupBox, QSpinBox\\n + from PyQt6.QtWidgets import QHBoxLayout, QVBoxLayout, QSpacerItem, QSizePolicy\\n + Qt.AlignRight = Qt.AlignmentFlag.AlignRight\\n + Qt.AlignTrailing = Qt.AlignmentFlag.AlignTrailing\\n + Qt.AlignVCenter = Qt.AlignmentFlag.AlignVCenter\\n + Qt.Horizontal = Qt.Orientation.Horizontal\\n + QSizePolicy.Fixed = QSizePolicy.Policy.Fixed\\n + QSizePolicy.Minimum = QSizePolicy.Policy.Minimum\\n + QDialogButtonBox.Cancel = QDialogButtonBox.StandardButton.Cancel\\n + QDialogButtonBox.Ok = QDialogButtonBox.StandardButton.Ok\\n + QDialogButtonBox.RestoreDefaults = QDialogButtonBox.StandardButton.RestoreDefaults\\n +except ImportError:\\n + from PyQt5.QtCore import Qt, QCoreApplication, QMetaObject\\n + from PyQt5.QtWidgets import QCheckBox, QComboBox, QDialogButtonBox, QLabel, QGroupBox, QSpinBox\\n + from PyQt5.QtWidgets import QHBoxLayout, QVBoxLayout, QSpacerItem, QSizePolicy +endef + +export UI_IMPORTS + regen: ui_settings.py ui_%.py: %.ui $(PYUIC) $< -o $@ + sed -i 's/QtCore.//g' $@ + sed -i 's/QtGui.//g' $@ + sed -i 's/QtWidgets.//g' $@ + sed -i 's/_translate = QCoreApplication.translate/_tr = QCoreApplication.translate/' $@ + sed -i 's/_translate(/_tr(/g' $@ + sed -i 's/"WineASIOSettings"/self.OBJECT_NAME/g' $@ + sed -i 's/ # type: ignore//g' $@ + sed -i 's/WineASIOSettings(object):/WineASIOSettings(object):\n OBJECT_NAME = "WineASIOSettings"\n/' $@ + sed -i 's/from PyQt5 import QtWidgets/$(shell echo "$$UI_IMPORTS")/' $@ + sed -i 's/ except ImportError:/except ImportError:/' $@ # --------------------------------------------------------------------------------------------------------------------- diff --git a/gui/settings.py b/gui/settings.py index 68da979..5fbb281 100755 --- a/gui/settings.py +++ b/gui/settings.py @@ -2,7 +2,7 @@ # -*- coding: utf-8 -*- # WineASIO Settings GUI -# Copyright (C) 2020 Filipe Coelho +# Copyright (C) 2020-2025 Filipe Coelho # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -21,8 +21,15 @@ import os import sys -from PyQt5.QtCore import pyqtSlot, QDir -from PyQt5.QtWidgets import QApplication, QDialog, QDialogButtonBox +try: + from PyQt6.QtCore import pyqtSlot, QDir + from PyQt6.QtWidgets import QApplication, QDialog, QDialogButtonBox + QDialogButtonBox.RestoreDefaults = QDialogButtonBox.StandardButton.RestoreDefaults + useQt6 = True +except ImportError: + from PyQt5.QtCore import pyqtSlot, QDir + from PyQt5.QtWidgets import QApplication, QDialog, QDialogButtonBox + useQt6 = False # --------------------------------------------------------------------------------------------------------------------- @@ -38,7 +45,7 @@ WINEPREFIX = os.getenv("WINEPREFIX") if not WINEPREFIX: WINEPREFIX = os.path.join(HOME, ".wine") -WINEASIO_PREFIX = "HKEY_CURRENT_USER\Software\Wine\WineASIO" +WINEASIO_PREFIX = "HKEY_CURRENT_USER\\Software\\Wine\\WineASIO" # --------------------------------------------------------------------------------------------------------------------- @@ -137,7 +144,7 @@ class WineASIOSettingsDialog(QDialog, Ui_WineASIOSettings): def slot_saveSettings(self): REGFILE = 'REGEDIT4\n' REGFILE += '\n' - REGFILE += '[HKEY_CURRENT_USER\Software\Wine\WineASIO]\n' + REGFILE += '[HKEY_CURRENT_USER\\Software\\Wine\\WineASIO]\n' REGFILE += '"Autostart server"=dword:0000000%i\n' % int(1 if self.cb_jack_autostart.isChecked() else 0) REGFILE += '"Connect to hardware"=dword:0000000%i\n' % int(1 if self.cb_ports_connect_hw.isChecked() else 0) REGFILE += '"Fixed buffersize"=dword:0000000%i\n' % int(1 if self.cb_jack_fixed_bsize.isChecked() else 0) @@ -164,6 +171,7 @@ if __name__ == '__main__': gui.show() # Exit properly - sys.exit(app.exec_()) + ret = app.exec() if useQt6 else app.exec_() + sys.exit(ret) # --------------------------------------------------------------------------------------------------------------------- diff --git a/gui/settings.ui b/gui/settings.ui index 077b3d5..66e5e46 100644 --- a/gui/settings.ui +++ b/gui/settings.ui @@ -11,7 +11,7 @@ - Dialog + WineASIO Settings @@ -180,8 +180,9 @@ Default is off - When on, an asio app will be able to change the jack buffer size. -Default is off + When on: ASIO applications will respect the current JACK buffer size +When off: ASIO applications can change the JACK buffer size +Default is on Fixed buffersize diff --git a/gui/ui_settings.py b/gui/ui_settings.py index f7b7576..9c96b2f 100644 --- a/gui/ui_settings.py +++ b/gui/ui_settings.py @@ -1,28 +1,31 @@ -#!/usr/bin/env python3 # -*- coding: utf-8 -*- -# WineASIO Settings GUI -# Copyright (C) 2020 Filipe Coelho +# Form implementation generated from reading ui file 'settings.ui' # -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# any later version. +# Created by: PyQt5 UI code generator 5.15.11 # -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# For a full copy of the GNU General Public License see the COPYING.GUI file - -# --------------------------------------------------------------------------------------------------------------------- +# WARNING: Any manual changes made to this file will be lost when pyuic5 is +# run again. Do not edit this file unless you know what you are doing. + + +try: + from PyQt6.QtCore import Qt, QCoreApplication, QMetaObject + from PyQt6.QtWidgets import QCheckBox, QComboBox, QDialogButtonBox, QLabel, QGroupBox, QSpinBox + from PyQt6.QtWidgets import QHBoxLayout, QVBoxLayout, QSpacerItem, QSizePolicy + Qt.AlignRight = Qt.AlignmentFlag.AlignRight + Qt.AlignTrailing = Qt.AlignmentFlag.AlignTrailing + Qt.AlignVCenter = Qt.AlignmentFlag.AlignVCenter + Qt.Horizontal = Qt.Orientation.Horizontal + QSizePolicy.Fixed = QSizePolicy.Policy.Fixed + QSizePolicy.Minimum = QSizePolicy.Policy.Minimum + QDialogButtonBox.Cancel = QDialogButtonBox.StandardButton.Cancel + QDialogButtonBox.Ok = QDialogButtonBox.StandardButton.Ok + QDialogButtonBox.RestoreDefaults = QDialogButtonBox.StandardButton.RestoreDefaults +except ImportError: + from PyQt5.QtCore import Qt, QCoreApplication, QMetaObject + from PyQt5.QtWidgets import QCheckBox, QComboBox, QDialogButtonBox, QLabel, QGroupBox, QSpinBox + from PyQt5.QtWidgets import QHBoxLayout, QVBoxLayout, QSpacerItem, QSizePolicy -from PyQt5.QtCore import Qt, QCoreApplication, QMetaObject -from PyQt5.QtWidgets import QCheckBox, QComboBox, QDialogButtonBox, QLabel, QGroupBox, QSpinBox -from PyQt5.QtWidgets import QHBoxLayout, QVBoxLayout, QSpacerItem, QSizePolicy - -# --------------------------------------------------------------------------------------------------------------------- class Ui_WineASIOSettings(object): OBJECT_NAME = "WineASIOSettings" @@ -112,53 +115,30 @@ class Ui_WineASIOSettings(object): self.buttonBox.rejected.connect(WineASIOSettings.reject) QMetaObject.connectSlotsByName(WineASIOSettings) -# --------------------------------------------------------------------------------------------------------------------- - def retranslateUi(self, WineASIOSettings): _tr = QCoreApplication.translate WineASIOSettings.setWindowTitle(_tr(self.OBJECT_NAME, "WineASIO Settings")) - - # Audio Ports self.group_ports.setTitle(_tr(self.OBJECT_NAME, "Audio Ports")) - + self.label_ports_in.setToolTip(_tr(self.OBJECT_NAME, "Number of jack ports that wineasio will try to open.\n" +"Default is 16")) self.label_ports_in.setText(_tr(self.OBJECT_NAME, "Number of inputs:")) - self.label_ports_in.setToolTip(_tr(self.OBJECT_NAME, - "Number of jack ports that wineasio will try to open.\n" - "Default is 16")) - - self.sb_ports_in.setToolTip(_tr(self.OBJECT_NAME, - "Number of jack ports that wineasio will try to open.\n" - "Default is 16")) - + self.sb_ports_in.setToolTip(_tr(self.OBJECT_NAME, "Number of jack ports that wineasio will try to open.\n" +"Default is 16")) + self.label_ports_out.setToolTip(_tr(self.OBJECT_NAME, "Number of jack ports that wineasio will try to open.\n" +"Default is 16")) self.label_ports_out.setText(_tr(self.OBJECT_NAME, "Number of outputs:")) - self.label_ports_out.setToolTip(_tr(self.OBJECT_NAME, - "Number of jack ports that wineasio will try to open.\n" - "Default is 16")) - - self.sb_ports_out.setToolTip(_tr(self.OBJECT_NAME, - "Number of jack ports that wineasio will try to open.\n" - "Default is 16")) - + self.sb_ports_out.setToolTip(_tr(self.OBJECT_NAME, "Number of jack ports that wineasio will try to open.\n" +"Default is 16")) + self.cb_ports_connect_hw.setToolTip(_tr(self.OBJECT_NAME, "Try to connect the asio channels to the\n" +"physical I/O ports on your hardware.\n" +"Default is on")) self.cb_ports_connect_hw.setText(_tr(self.OBJECT_NAME, "Connect to hardware")) - self.cb_ports_connect_hw.setToolTip(_tr(self.OBJECT_NAME, - "Try to connect the asio channels to the\n" - "physical I/O ports on your hardware.\n" - "Default is on")) - - # JACK Options self.group_jack.setTitle(_tr(self.OBJECT_NAME, "JACK Options")) - + self.cb_jack_autostart.setToolTip(_tr(self.OBJECT_NAME, "Enable wineasio to launch the jack server.\n" +"Default is off")) self.cb_jack_autostart.setText(_tr(self.OBJECT_NAME, "Autostart server")) - self.cb_jack_autostart.setToolTip(_tr(self.OBJECT_NAME, - "Enable wineasio to launch the jack server.\n" - "Default is off")) - + self.cb_jack_fixed_bsize.setToolTip(_tr(self.OBJECT_NAME, "When on: ASIO applications will respect the current JACK buffer size\n" +"When off: ASIO applications can change the JACK buffer size\n" +"Default is on")) self.cb_jack_fixed_bsize.setText(_tr(self.OBJECT_NAME, "Fixed buffersize")) - self.cb_jack_fixed_bsize.setToolTip(_tr(self.OBJECT_NAME, - "When on: ASIO applications will respect the current JACK buffer size\n" - "When off: ASIO applications can change the JACK buffer size" - "Default is on")) - self.label_jack_buffer_size.setText(_tr(self.OBJECT_NAME, "Preferred buffersize:")) - -# ---------------------------------------------------------------------------------------------------------------------