From d2b1cb999adcb7366588c54141c735545703b3d7 Mon Sep 17 00:00:00 2001 From: Thomas Peetz Date: Sat, 11 Jan 2025 01:54:05 +0100 Subject: [PATCH] reorganize files for Qt application --- gui/resources.py | 7 -- qt/.gitignore | 2 + {gui => qt}/database/__init__.py | 50 ++---------- {gui => qt}/database/base.py | 0 {gui => qt}/database/comic.py | 0 {gui => qt}/database/media.py | 0 {gui => qt}/database/metadata.py | 11 ++- qt/gui/__init__.py | 0 {gui => qt/gui}/dialogs.py | 0 gui/kontor.py => qt/gui/main_window.py | 21 +---- {gui => qt/gui}/model_config.py | 1 - {gui => qt/gui}/table_model.py | 2 +- qt/kontor.py | 21 +++++ qt/pysidedeploy.spec | 98 ++++++++++++++++++++++++ {gui => qt}/res/application-export.png | Bin {gui => qt}/res/application-import.png | Bin {gui => qt}/res/arrow-circle-double.png | Bin {gui => qt}/res/cross.png | Bin {gui => qt}/res/tick.png | Bin 19 files changed, 136 insertions(+), 77 deletions(-) delete mode 100644 gui/resources.py create mode 100644 qt/.gitignore rename {gui => qt}/database/__init__.py (63%) rename {gui => qt}/database/base.py (100%) rename {gui => qt}/database/comic.py (100%) rename {gui => qt}/database/media.py (100%) rename {gui => qt}/database/metadata.py (80%) create mode 100644 qt/gui/__init__.py rename {gui => qt/gui}/dialogs.py (100%) rename gui/kontor.py => qt/gui/main_window.py (90%) rename {gui => qt/gui}/model_config.py (98%) rename {gui => qt/gui}/table_model.py (98%) create mode 100644 qt/kontor.py create mode 100755 qt/pysidedeploy.spec rename {gui => qt}/res/application-export.png (100%) rename {gui => qt}/res/application-import.png (100%) rename {gui => qt}/res/arrow-circle-double.png (100%) rename {gui => qt}/res/cross.png (100%) rename {gui => qt}/res/tick.png (100%) diff --git a/gui/resources.py b/gui/resources.py deleted file mode 100644 index c135d07..0000000 --- a/gui/resources.py +++ /dev/null @@ -1,7 +0,0 @@ -from PySide6.QtGui import QIcon - -tick = QIcon('tick.png') -cross = QIcon('cross.png') -import_icon = QIcon("application-import.png") -export_icon = QIcon("application-export.png") -circle_icon = QIcon("arrow-circle-double.png") diff --git a/qt/.gitignore b/qt/.gitignore new file mode 100644 index 0000000..38b154f --- /dev/null +++ b/qt/.gitignore @@ -0,0 +1,2 @@ +deployment/ +kontor.bin diff --git a/gui/database/__init__.py b/qt/database/__init__.py similarity index 63% rename from gui/database/__init__.py rename to qt/database/__init__.py index 122959e..c6d21a1 100644 --- a/gui/database/__init__.py +++ b/qt/database/__init__.py @@ -1,5 +1,5 @@ import mariadb -from sqlalchemy import create_engine, text, MetaData, join +from sqlalchemy import create_engine, select, text, MetaData, join from sqlalchemy.orm import DeclarativeBase, relationship, sessionmaker from database.base import Base @@ -31,54 +31,20 @@ class KontorDB: self.session = __session__() def get_table_id(self, table_name): - cursor = self.db_conn.cursor() - cursor.execute("SELECT id, created_date, last_modified_date FROM meta_data_table WHERE table_name=?", - (table_name,)) - row = cursor.fetchone() - cursor.close() - # table_ids = self.session.query(MetaDataTable).filter(MetaDataTable.table_name == table_name).all() - # print(type(table_ids)) - return row[0] + result = self.session.execute(select(MetaDataTable.id).where(MetaDataTable.table_name == table_name)).scalar() + return result def get_table_names(self) -> list: - tables_names = [] - cursor = self.db_conn.cursor() - cursor.execute("SELECT id, table_name from meta_data_table") - rows = cursor.fetchall().all - for row in rows: - print(row) - for (_, table_name) in rows: - tables_names.append(table_name) - cursor.close() tables = self.session.query(MetaDataTable).all() - for table in tables: - print(table) - return tables_names + result = [table.table_name for table in tables] + return result - def get_column_meta_data(self, table_id: str, table_name: str): - cursor = self.db_conn.cursor() + def get_column_meta_data(self, table_id: str, table_name: str) -> dict: meta_data = {} - cursor.execute( - "SELECT column_name, column_order, column_label FROM meta_data_column WHERE table_id=? AND is_shown is true ORDER bY column_order", - (table_id,)) - rows = cursor.fetchall() order = 0 - for (column_name, column_order, column_label) in rows: - meta_data[order] = {'column': column_name, 'label': column_label, 'order': column_order} + for (_, column) in self.session.query(MetaDataTable, MetaDataColumn).filter(MetaDataTable.id == MetaDataColumn.table_id).filter(MetaDataTable.table_name == table_name).filter(MetaDataColumn.is_shown == 1).all(): + meta_data[order] = {'column': column.column_name, 'label': column.column_label, 'order': column.column_order} order += 1 - cursor.close() - columns = (self.session.query(MetaDataColumn). - join(MetaDataTable, MetaDataTable.id == MetaDataColumn.table_id). - filter(MetaDataTable.table_name == table_name). - filter(MetaDataColumn.is_shown is True). - order_by(MetaDataColumn.column_order).all()) - print(columns) - for column in columns: - print(column) - result = repr(column) - if result is not None: - print(result) - # print(f"retrieved {len(rows)} columns, set {len(meta_data)} headers") return meta_data def get_filters(self, table_id): diff --git a/gui/database/base.py b/qt/database/base.py similarity index 100% rename from gui/database/base.py rename to qt/database/base.py diff --git a/gui/database/comic.py b/qt/database/comic.py similarity index 100% rename from gui/database/comic.py rename to qt/database/comic.py diff --git a/gui/database/media.py b/qt/database/media.py similarity index 100% rename from gui/database/media.py rename to qt/database/media.py diff --git a/gui/database/metadata.py b/qt/database/metadata.py similarity index 80% rename from gui/database/metadata.py rename to qt/database/metadata.py index 8a59633..2fd0af7 100644 --- a/gui/database/metadata.py +++ b/qt/database/metadata.py @@ -14,11 +14,10 @@ class MetaDataTable(Base): table_columns = relationship("MetaDataColumn") def __repr__(self): - print(f'MetaDataTable({self.id} {self.table_name})') + return f'MetaDataTable({self.id} {self.table_name})' def __str__(self): - print(f'{self.table_name}({self.id})') - + return f'{self.table_name}({self.id})' class MetaDataColumn(Base): __tablename__ = 'meta_data_column' @@ -40,10 +39,10 @@ class MetaDataColumn(Base): def __repr__(self): if self.column_name is None: - print(f'MetaDataColumn({self.id} {self.table.table_name}.__)') + return f'MetaDataColumn({self.id} {self.table.table_name}.__)' else: - print(f'MetaDataColumn({self.id} {self.table.table_name}.{self.column_name})') + return f'MetaDataColumn({self.id} {self.table.table_name}.{self.column_name})' def __str__(self): - print(f'{self.column_name}({self.id})') + return f'{self.column_name}({self.id})' diff --git a/qt/gui/__init__.py b/qt/gui/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/gui/dialogs.py b/qt/gui/dialogs.py similarity index 100% rename from gui/dialogs.py rename to qt/gui/dialogs.py diff --git a/gui/kontor.py b/qt/gui/main_window.py similarity index 90% rename from gui/kontor.py rename to qt/gui/main_window.py index ea53ba5..ea288df 100644 --- a/gui/kontor.py +++ b/qt/gui/main_window.py @@ -1,14 +1,6 @@ -""" -PyQT6 GUI for Kontor -""" -import sys -from pathlib import Path - -import yaml from PySide6.QtGui import QAction, QIcon from PySide6.QtWidgets import QWidget, QVBoxLayout, QMenu, QMessageBox, QTabWidget, QTableView -from PySide6.QtWidgets import QApplication, QLabel, QMainWindow -from platformdirs import PlatformDirs +from PySide6.QtWidgets import QLabel, QMainWindow from database import KontorDB from dialogs import ExportKontorDialog, ImportKontorDialog @@ -138,14 +130,3 @@ class MainWindow(QMainWindow): layout.addWidget(table_view) model.refresh() return data_tab - - -if __name__ == '__main__': - app = QApplication(sys.argv) - dirs = PlatformDirs("kontor") - database_config = Path(dirs.user_config_dir, 'database-config.yaml') - with open(database_config, 'rt') as f: - db_config = yaml.safe_load(f.read()) - window = MainWindow(db_config) - window.show() - app.exec() diff --git a/gui/model_config.py b/qt/gui/model_config.py similarity index 98% rename from gui/model_config.py rename to qt/gui/model_config.py index abff7da..01d3805 100644 --- a/gui/model_config.py +++ b/qt/gui/model_config.py @@ -2,7 +2,6 @@ import mariadb from PySide6.QtWidgets import QHBoxLayout, QCheckBox from database import KontorDB -from database.comic import Comic class KontorModelConfig: diff --git a/gui/table_model.py b/qt/gui/table_model.py similarity index 98% rename from gui/table_model.py rename to qt/gui/table_model.py index 2af11c9..5e80c3b 100644 --- a/gui/table_model.py +++ b/qt/gui/table_model.py @@ -3,7 +3,7 @@ from datetime import datetime from PySide6.QtCore import QAbstractTableModel, QModelIndex from PySide6.QtGui import Qt -from model_config import KontorModelConfig +from gui.model_config import KontorModelConfig class KontorTableModel(QAbstractTableModel): diff --git a/qt/kontor.py b/qt/kontor.py new file mode 100644 index 0000000..2eed73b --- /dev/null +++ b/qt/kontor.py @@ -0,0 +1,21 @@ +""" +PyQT6 GUI for Kontor +""" +import sys +from pathlib import Path +from platformdirs import PlatformDirs +from PySide6.QtWidgets import QApplication +import yaml + +from gui.main_window import MainWindow + + +if __name__ == '__main__': + app = QApplication(sys.argv) + dirs = PlatformDirs("kontor") + database_config = Path(dirs.user_config_dir, 'database-config.yaml') + with open(database_config, 'rt') as f: + db_config = yaml.safe_load(f.read()) + window = MainWindow(db_config) + window.show() + app.exec() diff --git a/qt/pysidedeploy.spec b/qt/pysidedeploy.spec new file mode 100755 index 0000000..8e65745 --- /dev/null +++ b/qt/pysidedeploy.spec @@ -0,0 +1,98 @@ +[app] + +# title of your application +title = kontor + +# project directory. the general assumption is that project_dir is the parent directory +# of input_file +project_dir = /home/tpeetz/projects/kontor/qt + +# source file path +input_file = /home/tpeetz/projects/kontor/qt/kontor.py + +# directory where exec is stored +exec_directory = . + +# path to .pyproject project file +project_file = + +# application icon +icon = /usr/local/lib/python3.11/dist-packages/PySide6/scripts/deploy_lib/pyside_icon.jpg + +[python] + +# python path +python_path = /usr/bin/python3 + +# python packages to install +packages = Nuitka==2.4.8 + +# buildozer = for deploying Android application +android_packages = buildozer==1.5.0,cython==0.29.33 + +[qt] + +# comma separated path to qml files required +# normally all the qml files required by the project are added automatically +qml_files = + +# excluded qml plugin binaries +excluded_qml_plugins = + +# qt modules used. comma separated +modules = Gui,DBus,Core,Widgets + +# qt plugins used by the application +plugins = platformthemes,imageformats,platforms,generic,iconengines,egldeviceintegrations,styles,xcbglintegrations,platforms/darwin,platforminputcontexts,accessiblebridge + +[android] + +# path to pyside wheel +wheel_pyside = + +# path to shiboken wheel +wheel_shiboken = + +# plugins to be copied to libs folder of the packaged application. comma separated +plugins = + +[nuitka] + +# usage description for permissions requested by the app as found in the info.plist file +# of the app bundle +# eg = extra_args = --show-modules --follow-stdlib +macos.permissions = + +# mode of using nuitka. accepts standalone or onefile. default is onefile. +mode = onefile + +# (str) specify any extra nuitka arguments +extra_args = --quiet --noinclude-qt-translations + +[buildozer] + +# build mode +# possible options = [release, debug] +# release creates an aab, while debug creates an apk +mode = debug + +# contrains path to pyside6 and shiboken6 recipe dir +recipe_dir = + +# path to extra qt android jars to be loaded by the application +jars_dir = + +# if empty uses default ndk path downloaded by buildozer +ndk_path = + +# if empty uses default sdk path downloaded by buildozer +sdk_path = + +# other libraries to be loaded. comma separated. +# loaded at app startup +local_libs = + +# architecture of deployed platform +# possible values = ["aarch64", "armv7a", "i686", "x86_64"] +arch = + diff --git a/gui/res/application-export.png b/qt/res/application-export.png similarity index 100% rename from gui/res/application-export.png rename to qt/res/application-export.png diff --git a/gui/res/application-import.png b/qt/res/application-import.png similarity index 100% rename from gui/res/application-import.png rename to qt/res/application-import.png diff --git a/gui/res/arrow-circle-double.png b/qt/res/arrow-circle-double.png similarity index 100% rename from gui/res/arrow-circle-double.png rename to qt/res/arrow-circle-double.png diff --git a/gui/res/cross.png b/qt/res/cross.png similarity index 100% rename from gui/res/cross.png rename to qt/res/cross.png diff --git a/gui/res/tick.png b/qt/res/tick.png similarity index 100% rename from gui/res/tick.png rename to qt/res/tick.png