# # !/home/linuxero/proj/tero/pyqcrm/.qtcreator/venv-3.13.1/bin/python3 """! @brief CRM for cleaning services written in Python, PySide6 and QtQuick.""" ## # @mainpage PYQCRM - Qt for Python CRM # # @section description_main Description # A CRM program for digitally manageing the business of cleaning # services company. # # @section notes_main Notes # - The project is built using QtCreator 6.8.x # - Minimum Python version 3.13.x # - PySide6 # # Copyright (c) 2025 Schnaxero. All rights reserved. ## # @file main.py # # @brief Main entry point of the program # # @section description_pyqcrm Description # Initialization of the program goes here. Various global functions called from the entry point. # The GUI application is set up and started here. # # @section libraries_main Libraries/Modules # - os standard library # - Access to environ, a mapping object of keys and values to set an environment variable. # - sys standard library # - Access to argv and system functions. # - logging standard library # - Access to logging functions. # - QLocalServer PySide6 class # - Provides a local socket based server. # - QLocalSocket PySide6 class # - Provides a local socket. # - QSystemTrayIcon PySide6 class # - Provides an icon for the application in the system tray. # - QIcon PySide6 class # - Provides scalable icons in different modes and states. # - QGuiApplication PySide6 class # - Manages the GUI application’s control flow and main settings. # - QQmlApplicationEngine PySide6 class # - Provides a convenient way to load an application from a single QML file. # - QIODevice PySide6 class # - Base interface class of all I/O devices in Qt. # - lib module (local) # - Backbone classes to run the program. # # @section notes_pyqcrm Notes # - Install dependencies (See requirements.txt). # # @section todo_pyqcrm TODO # - A lot of nice-to-haves. # # @section author_pyqcrm Author(s) # - Created by Linuxero on 03/14/2025. # - Modified by Linuxero on 03/14/2025. # # Copyright (c) 2025 Schnaxero. All rights reserved. # Imports import os import sys import logging from PySide6.QtNetwork import QLocalServer, QLocalSocket from PySide6.QtWidgets import QSystemTrayIcon from PySide6.QtGui import QGuiApplication, QIcon from PySide6.QtQml import QQmlApplicationEngine from PySide6.QtCore import QIODevice #, QResource from lib.ConfigLoader import ConfigLoader from lib.DB.BusinessModel import BusinessModel import rc_pyqcrm import rc_qml from lib.DB.DbManager import DbManager from lib.DB.UserManager import UserManager from lib.DB.AddressModel import AddressModel from lib.DB.BTypeModel import BTypeModel from lib.DB.ContactModel import ContactModel from lib.DB.EmployeeModel import EmployeeModel from lib.DB.ObjectModel import ObjectModel from lib.Printers import Printers # Environment settings ## Allow local file read. os.environ['QML_XHR_ALLOW_FILE_READ'] = '1' # [pyqcrm] # program-name="" # version= # [database] # server="" # port= # user="" # password="" # name="" # type="" # Global Constants ## Configuration availability. bad_config = False ## Database connection available. db_con = False ## The model class for address manipulation. address_model = None ## The model class for customer manipulation. business_model = None ## The model class for customer type manipulation. business_type = None ## The model class for contact manipulation. contact_model = None ## The model class for employee manipulation. employee_model = None ## The model class for object manipulation. object_model = None ## The class of available printers on the system. printers = None ## The logged-in user. user = None # Functions def initializeProgram(): """! Initializes the program.""" print(f"In {__file__} file, initializeProgram()") global address_model, bad_config, business_model, user, business_type, contact_model, employee_model, object_model, db_con, printers if not bad_config: dbconf = config.getConfig()['database'] DbManager(dbconf) printers = Printers() if DbManager().getConnection(): db_con = True user = UserManager() business_model = BusinessModel() address_model = AddressModel() business_type = BTypeModel() contact_model = ContactModel() employee_model = EmployeeModel() object_model = ObjectModel() publishContext() def configReady(): """! Slot to respond to the validity of the configuration.""" global bad_config bad_config = False initializeProgram() def publishContext(): """! Connect necessary modules to the QML GUI.""" # print(f"In {__file__} file, publishContext()") global engine, address_model, bad_config, business_model, user, business_type, contact_model, object_model, employee_model, printers engine.rootContext().setContextProperty("loggedin_user", user) engine.rootContext().setContextProperty("business_model", business_model) engine.rootContext().setContextProperty("address_model", address_model) engine.rootContext().setContextProperty("business_type", business_type) engine.rootContext().setContextProperty("contact_model", contact_model) engine.rootContext().setContextProperty("employee_model", employee_model) engine.rootContext().setContextProperty("object_model", object_model) # Entry point of the program if __name__ == "__main__": #QResource.registerResource("rc_qml.py") app = QGuiApplication(sys.argv) engine = QQmlApplicationEngine() pyq_sok = QLocalSocket() pyq_sok.connectToServer("PYQCRM_INSTANCE", QIODevice.ReadOnly) if pyq_sok.state() == QLocalSocket.ConnectedState: print("PYQCRM already running..") print("Stop the running instance before running the application..") sys.exit(-1) else: print("Starting PYQCRM_INSTANCE") pyq_server = QLocalServer() pyq_server.listen("PYQCRM_INSTANCE") engine.addImportPath("qrc:/") engine.addImportPath("qrc:/Style") # qml_file = Path(__file__).resolve().parent / "Gui/main.qml" qml_file = "qrc:/Gui/main.qml" icon = QIcon(":/images/tero.jpg") app.setWindowIcon(icon) tray = QSystemTrayIcon() tray.setIcon(icon) tray.setToolTip("PYQCRM") config = ConfigLoader() if not config.getConfig(): bad_config = True config.configurationReady.connect(configReady) else: initializeProgram() engine.rootContext().setContextProperty("config", config) engine.rootContext().setContextProperty("sys_printers", printers) engine.rootContext().setContextProperty("bad_config", bad_config) # print(f"Fehler: {i}") engine.rootContext().setContextProperty("db_con", db_con) engine.rootContext().setContextProperty("systray", tray) engine.load(qml_file) if not engine.rootObjects(): sys.exit(-1) sys.exit(app.exec())