def __init__(self, *args, **kwargs): """ All the necessary initializations. Is shown at the end. """ super().__init__(*args, **kwargs) # set geometry self.setGeometry(tools.get_option(constants.Option.MAINWINDOW_BOUNDS)) # set icon self.setWindowIcon(tools.load_ui_icon('window.icon.ico')) # set title self.setWindowTitle('Imperialism Remake') # just a layout but nothing else self.layout = QtWidgets.QHBoxLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) self.content = None # show in full screen, maximized or normal if tools.get_option(constants.Option.MAINWINDOW_FULLSCREEN): self.setWindowFlags(self.windowFlags() | QtCore.Qt.FramelessWindowHint) self.showFullScreen() elif tools.get_option(constants.Option.MAINWINDOW_MAXIMIZED): self.showMaximized() else: self.show() # loading animation # TODO animation right and start, stop in client self.animation = QtGui.QMovie(constants.extend(constants.GRAPHICS_UI_FOLDER, 'loading.gif')) # self.animation.start() self.loading_label = QtWidgets.QLabel(self, flags=QtCore.Qt.FramelessWindowHint | QtCore.Qt.Window) self.loading_label.setAttribute(QtCore.Qt.WA_TranslucentBackground) self.loading_label.setMovie(self.animation)
def close_request(self, parent_widget): """ User wants to close the dialog, check if an option has been changed. If an option has been changed, ask for okay from user and update the options. Also react on some updated options (others might only take affect after a restart of the application). We immediately : start/stop music (mute option) :param parent_widget: :return: """ # check if something was changed options_modified = any([box.isChecked() is not tools.get_option(option) for (box, option) in self._check_boxes]) # TODO line edits and sliders if options_modified: answer = QtWidgets.QMessageBox.question(parent_widget, 'Preferences', 'Save modified preferences', QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.Yes) if answer == QtWidgets.QMessageBox.Yes: # all _check_boxes for (box, option) in self._check_boxes: tools.set_option(option, box.isChecked()) # start/stop audio player (depending on mute) if tools.get_option(constants.Option.SOUNDTRACK_MUTE): audio.soundtrack_player.stop() pass else: audio.soundtrack_player.play() pass return True
def __init__(self, *args, **kwargs): """ All the necessary initializations. Is shown at the end. """ super().__init__(*args, **kwargs) # set geometry self.setGeometry(tools.get_option(constants.Option.MAINWINDOW_BOUNDS)) # set title self.setWindowTitle('Imperialism Remake') # just a layout but nothing else self.layout = QtWidgets.QHBoxLayout(self) self.layout.setContentsMargins(0, 0, 0, 0) self.content = None # show in full screen, maximized or normal if tools.get_option(constants.Option.MAINWINDOW_FULLSCREEN): self.setWindowFlags(self.windowFlags() | QtCore.Qt.FramelessWindowHint) self.showFullScreen() elif tools.get_option(constants.Option.MAINWINDOW_MAXIMIZED): self.showMaximized() else: self.show() # loading animation # TODO animation right and start, stop in client self.animation = QtGui.QMovie( constants.extend(constants.GRAPHICS_UI_FOLDER, 'loading.gif')) # self.animation.start() self.loading_label = QtWidgets.QLabel( self, flags=QtCore.Qt.FramelessWindowHint | QtCore.Qt.Window) self.loading_label.setAttribute(QtCore.Qt.WA_TranslucentBackground) self.loading_label.setMovie(self.animation)
def close_request(self, parent_widget): """ User wants to close the dialog, check if an option has been changed. If an option has been changed, ask for okay from user and update the options. Also react on some updated options (others might only take affect after a restart of the application). We immediately : start/stop music (mute option) :param parent_widget: :return: """ # check if something was changed options_modified = any([ box.isChecked() is not tools.get_option(option) for (box, option) in self._check_boxes ]) # TODO line edits and sliders if options_modified: answer = QtWidgets.QMessageBox.question( parent_widget, 'Preferences', 'Save modified preferences', QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No, QtWidgets.QMessageBox.Yes) if answer == QtWidgets.QMessageBox.Yes: # all _check_boxes for (box, option) in self._check_boxes: tools.set_option(option, box.isChecked()) # start/stop audio player (depending on mute) if tools.get_option(constants.Option.SOUNDTRACK_MUTE): audio.soundtrack_player.stop() pass else: audio.soundtrack_player.play() pass return True
def start_client(): """ Creates the Qt application and shows the main window. """ logger.debug('start_client') # create app app = QtWidgets.QApplication([]) # test for desktop availability desktop = app.desktop() rect = desktop.screenGeometry() if ((rect.width() < constants.MINIMAL_SCREEN_SIZE[0]) or (rect.height() < constants.MINIMAL_SCREEN_SIZE[1])): # noinspection PyTypeChecker QtWidgets.QMessageBox.warning( None, 'Warning', 'Actual screen size below minimal screen size {}.'.format( constants.MINIMAL_SCREEN_SIZE)) return # if no bounds are set, set reasonable bounds if tools.get_option(constants.Option.MAINWINDOW_BOUNDS) is None: tools.set_option( constants.Option.MAINWINDOW_BOUNDS, desktop.availableGeometry().adjusted(50, 50, -100, -100)) tools.set_option(constants.Option.MAINWINDOW_MAXIMIZED, True) logger.info( 'No previous bounds of the main window stored, start maximized') # load global stylesheet to app # open is 'r' by default with open(constants.GLOBAL_STYLESHEET_FILE, encoding='utf-8') as file: style_sheet = file.read() app.setStyleSheet(style_sheet) # set icon app.setWindowIcon(tools.load_ui_icon('window.icon.ico')) # setup sound system audio.load_soundtrack_playlist() audio.setup_soundtrack_player() # start audio player if wished if not tools.get_option(constants.Option.SOUNDTRACK_MUTE): audio.soundtrack_player.play() # create client object and switch to start screen client = Client() client.switch_to_start_screen() # start Qt app execution and immediately try to connect to local server logger.info('client initialized (pid=%d), start Qt app execution', os.getpid()) # noinspection PyCallByClass QtCore.QTimer.singleShot(0, local_network_connect) app.exec_()
def __init__(self): """ Create the main window, the help browser dialog, the audio player, ... """ # main window self.main_window = QtWidgets.QWidget() # set geometry self.main_window.setGeometry( tools.get_option(constants.Option.MAINWINDOW_BOUNDS)) # set title self.main_window.setWindowTitle('Imperialism Remake') # show in full screen, maximized or normal if tools.get_option(constants.Option.MAINWINDOW_FULLSCREEN): self.main_window.setWindowFlags(self.main_window.windowFlags() | QtCore.Qt.FramelessWindowHint) self.main_window.showFullScreen() elif tools.get_option(constants.Option.MAINWINDOW_MAXIMIZED): self.main_window.showMaximized() else: self.main_window.show() # widget switcher self.widget_switcher = qt.WidgetSwitcher(self.main_window) # help browser # TODO help browser only if QtWebEngineWidgets available (or preferences) # self.help_browser_widget = qt.BrowserWidget(tools.load_ui_icon) # self.help_browser_widget = qt.BrowserWidget(tools.load_ui_icon) # self.help_browser_widget.home_url = tools.local_url(constants.DOCUMENTATION_INDEX_FILE) # self.help_browser_widget.home() # self.help_dialog = graphics.GameDialog(self.main_window, self.help_browser_widget, title='Help') # self.help_dialog.setFixedSize(QtCore.QSize(800, 600)) # move to lower right border, so that overlap with other windows is not that strong # self.help_dialog.move(self.main_window.x() + self.main_window.width() - 800, # self.main_window.y() + self.main_window.height() - 600) # add help browser keyboard shortcut action = QtWidgets.QAction(self.main_window) action.setShortcut(QtGui.QKeySequence('F1')) action.triggered.connect(self.show_help_browser) self.main_window.addAction(action) # add server monitor keyboard shortcut action = QtWidgets.QAction(self.main_window) action.setShortcut(QtGui.QKeySequence('F2')) action.triggered.connect(self.show_server_monitor) self.main_window.addAction(action) # for the notifications self.pending_notifications = [] self.notification_position_constraint = qt.RelativeLayoutConstraint().center_horizontal()\ .south(20) self.notification = None # after the player starts, the main window is not active anymore # set it active again or it doesn't get keyboard focus self.main_window.activateWindow()
def __init__(self): """ Create the main window, the help browser dialog, the audio player, ... """ # main window self.main_window = QtWidgets.QWidget() # set geometry self.main_window.setGeometry(tools.get_option(constants.Option.MAINWINDOW_BOUNDS)) # set title self.main_window.setWindowTitle('Imperialism Remake') # show in full screen, maximized or normal if tools.get_option(constants.Option.MAINWINDOW_FULLSCREEN): self.main_window.setWindowFlags(self.main_window.windowFlags() | QtCore.Qt.FramelessWindowHint) self.main_window.showFullScreen() elif tools.get_option(constants.Option.MAINWINDOW_MAXIMIZED): self.main_window.showMaximized() else: self.main_window.show() # widget switcher self.widget_switcher = qt.WidgetSwitcher(self.main_window) # help browser # TODO help browser only if QtWebEngineWidgets available (or preferences) # self.help_browser_widget = qt.BrowserWidget(tools.load_ui_icon) # self.help_browser_widget = qt.BrowserWidget(tools.load_ui_icon) # self.help_browser_widget.home_url = tools.local_url(constants.DOCUMENTATION_INDEX_FILE) # self.help_browser_widget.home() # self.help_dialog = graphics.GameDialog(self.main_window, self.help_browser_widget, title='Help') # self.help_dialog.setFixedSize(QtCore.QSize(800, 600)) # move to lower right border, so that overlap with other windows is not that strong # self.help_dialog.move(self.main_window.x() + self.main_window.width() - 800, # self.main_window.y() + self.main_window.height() - 600) # add help browser keyboard shortcut action = QtWidgets.QAction(self.main_window) action.setShortcut(QtGui.QKeySequence('F1')) action.triggered.connect(self.show_help_browser) self.main_window.addAction(action) # add server monitor keyboard shortcut action = QtWidgets.QAction(self.main_window) action.setShortcut(QtGui.QKeySequence('F2')) action.triggered.connect(self.show_server_monitor) self.main_window.addAction(action) # for the notifications self.pending_notifications = [] self.notification_position_constraint = qt.RelativeLayoutConstraint().center_horizontal()\ .south(20) self.notification = None # after the player starts, the main window is not active anymore # set it active again or it doesn't get keyboard focus self.main_window.activateWindow()
def start_client(): """ Creates the Qt application and shows the main window. """ # create app app = QtWidgets.QApplication([]) # test for desktop availability desktop = app.desktop() rect = desktop.screenGeometry() if ((rect.width() < constants.MINIMAL_SCREEN_SIZE[0]) or (rect.height() < constants.MINIMAL_SCREEN_SIZE[1])): # noinspection PyTypeChecker QtWidgets.QMessageBox.warning(None, 'Warning', 'Actual screen size below minimal screen size {}.' .format(constants.MINIMAL_SCREEN_SIZE)) return # if no bounds are set, set reasonable bounds if tools.get_option(constants.Option.MAINWINDOW_BOUNDS) is None: tools.set_option(constants.Option.MAINWINDOW_BOUNDS, desktop.availableGeometry().adjusted(50, 50, -100, -100)) tools.set_option(constants.Option.MAINWINDOW_MAXIMIZED, True) logger.info('No previous bounds of the main window stored, start maximized') # load global stylesheet to app # open is 'r' by default with open(constants.GLOBAL_STYLESHEET_FILE, encoding='utf-8') as file: style_sheet = file.read() app.setStyleSheet(style_sheet) # set icon app.setWindowIcon(tools.load_ui_icon('window.icon.ico')) # setup sound system audio.load_soundtrack_playlist() audio.setup_soundtrack_player() # start audio player if wished if not tools.get_option(constants.Option.SOUNDTRACK_MUTE): audio.soundtrack_player.play() pass # create client object and switch to start screen client = Client() client.switch_to_start_screen() # start Qt app execution and immediately try to connect to local server logger.info('client initialized, start Qt app execution') # noinspection PyCallByClass QtCore.QTimer.singleShot(0, local_network_connect) app.exec_()
def _register_slider(self, slider, option): """ :param slider: :param option: """ slider.setValue(tools.get_option(option)) self._sliders.append((slider, option))
def _register_line_edit(self, edit, option): """ :param edit: :param option: """ edit.setText(tools.get_option(option)) self._line_edits.append((edit, option))
def _register_check_box(self, checkbox, option): """ Takes an option identifier (str) where the option value must be True/False and sets a checkbox according to the current value. Stores the checkbox, option pair in a list. :param checkbox: :param option: """ checkbox.setChecked(tools.get_option(option)) self._check_boxes.append((checkbox, option))
def local_network_connect(): """ Connect to a server running locally. """ # connect network client of client print('client tries to connect to server') local_network_client.connect_to_host(constants.NETWORK_PORT) # TODO what if this is not possible # tell name local_network_client.send(constants.C.GENERAL, constants.M.GENERAL_NAME, tools.get_option(constants.Option.LOCALCLIENT_NAME))
def local_network_connect(): """ Connect to a server running locally. """ # connect network client of client logger.info('client tries to connect to server') local_network_client.connect_to_host(constants.NETWORK_PORT) # TODO what if this is not possible # that should always be possible, if not, we should try again, and then throw an error # tell name local_network_client.send(constants.C.GENERAL, constants.M.GENERAL_NAME, tools.get_option(constants.Option.LOCALCLIENT_NAME))
def local_network_connect(): """ Connect to a server running locally. """ # connect network client of client print('client tries to connect to server') local_network_client.connect_to_host(constants.NETWORK_PORT) # TODO what if this is not possible # tell name local_network_client.send( constants.C.GENERAL, constants.M.GENERAL_NAME, tools.get_option(constants.Option.LOCALCLIENT_NAME))
def local_network_connect(): """ Connect to a server running locally. """ # connect network client of client logger.info('client tries to connect to server') local_network_client.connect_to_host(constants.NETWORK_PORT) # TODO what if this is not possible # that should always be possible, if not, we should try again, and then throw an error # tell name local_network_client.send( constants.C.GENERAL, constants.M.GENERAL_NAME, tools.get_option(constants.Option.LOCALCLIENT_NAME))
def send_client_name(self): logger.debug('send_client_name') self._network_client.send( constants.C.GENERAL, constants.M.GENERAL_NAME, tools.get_option(constants.Option.LOCALCLIENT_NAME))
def main(): """ Main entry point. Called from the script generated in setup.py and called when running this module with python. """ # test for python version required_version = (3, 5) if sys.version_info < required_version: raise RuntimeError('Python version must be {}.{} at least.'.format(*required_version)) # test for existence of PyQt5 try: from PyQt5 import QtCore except ImportError: raise RuntimeError('PyQt5 must be installed.') # fix PyQt5 exception eating fix_pyqt5_exception_eating() # set start directory set_start_directory() # determine user folder if os.name == 'posix': # Linux / Unix user_folder = os.path.join(os.getenv('HOME'), 'Imperialism Remake User Data') if (os.name == 'nt') and (os.getenv('USERPROFILE') is not None): # MS Windows user_folder = os.path.join(os.getenv('USERPROFILE'), 'Imperialism Remake User Data') else: user_folder = 'User Data' print(('user data stored in: {}'.format(user_folder))) # if not exist, create user folder if not os.path.isdir(user_folder): os.mkdir(user_folder) # determine DEBUG_MODE from runtime arguments from imperialism_remake.base import switches if len(sys.argv) > 1 and sys.argv[1] == 'debug': switches.DEBUG_MODE = True if switches.DEBUG_MODE: print('debug mode is on') # redirect output to log files (will be overwritten at each start) Log_File = os.path.join(user_folder, 'remake.log') Error_File = os.path.join(user_folder, 'remake.error.log') # in debug mode print to the console instead if not switches.DEBUG_MODE: import codecs sys.stdout = codecs.open(Log_File, encoding='utf-8', mode='w') sys.stderr = codecs.open(Error_File, encoding='utf-8', mode='w') # import some base libraries import imperialism_remake.base.tools as tools # search for existing options file, if not existing, save it once (should just save an empty dictionary) Options_File = os.path.join(user_folder, 'options.info') if not os.path.exists(Options_File): tools.save_options(Options_File) # create single options object, load options and send a log message tools.load_options(Options_File) tools.log_info('options loaded from user folder ({})'.format(user_folder)) # special case of some desktop environments under Linux where full screen mode does not work well from imperialism_remake.base import constants # full screen support if tools.get_option(constants.Option.MAINWINDOW_FULLSCREEN_SUPPORTED): session = os.environ.get("DESKTOP_SESSION") if session and (session.startswith('ubuntu') or 'xfce' in session or session.startswith('xubuntu') or 'gnome' in session): tools.set_option(constants.Option.MAINWINDOW_FULLSCREEN_SUPPORTED, False) tools.log_warning('Desktop environment {} has problems with full screen mode. Will turn if off.'.format(session)) # we cannot have full screen without support if not tools.get_option(constants.Option.MAINWINDOW_FULLSCREEN_SUPPORTED): tools.set_option(constants.Option.MAINWINDOW_FULLSCREEN, False) # now we can safely assume that the environment is good to us # start server import multiprocessing # multiprocessing.freeze_support() multiprocessing.set_start_method('spawn') from imperialism_remake.server.server import ServerProcess server_process = ServerProcess() server_process.start() # start client, we will return when the program finishes from imperialism_remake.client.client import start_client start_client() # wait for server server_process.join() # save options tools.save_options(Options_File) tools.log_info('options saved') # report on unused resources if switches.DEBUG_MODE: tools.find_unused_resources() # good bye message tools.log_info('will exit soon - good bye')
print('desktop geometry', rect, 'minimal required screen size', constants.MINIMAL_SCREEN_SIZE) # load global stylesheet to app with open(constants.GLOBAL_STYLESHEET_FILE, encoding='utf-8') as file: style_sheet = file.read() app.setStyleSheet(style_sheet) # set icon app.setWindowIcon(tools.load_ui_icon('window.icon.ico')) # main window main_window = QtWidgets.QWidget() # set geometry main_window.setGeometry( tools.get_option(constants.Option.MAINWINDOW_BOUNDS)) # set title main_window.setWindowTitle('Imperialism Remake') # show in full screen, maximized or normal if tools.get_option(constants.Option.MAINWINDOW_FULLSCREEN): main_window.setWindowFlags(main_window.windowFlags() | QtCore.Qt.FramelessWindowHint) main_window.showFullScreen() elif tools.get_option(constants.Option.MAINWINDOW_MAXIMIZED): main_window.showMaximized() else: main_window.show() # widget switcher widget_switcher = qt.WidgetSwitcher(main_window)
def main(): """ Main entry point. Called from the script generated in setup.py and called when running this module with python. """ # test for python version required_version = (3, 5) if sys.version_info < required_version: raise RuntimeError('Python version must be {}.{} at least.'.format(*required_version)) # test for existence of PyQt5 try: from PyQt5 import QtCore except ImportError: raise RuntimeError('PyQt5 must be installed.') # fix PyQt5 exception eating fix_pyqt5_exception_eating() # set start directory set_start_directory() # determine user folder if os.name == 'posix': # Linux / Unix user_folder = os.path.join(os.getenv('HOME'), 'Imperialism Remake User Data') if (os.name == 'nt') and (os.getenv('USERPROFILE') is not None): # MS Windows user_folder = os.path.join(os.getenv('USERPROFILE'), 'Imperialism Remake User Data') else: user_folder = 'User Data' print('user data stored in: {}'.format(user_folder)) # if not exist, create user folder if not os.path.isdir(user_folder): os.mkdir(user_folder) # determine DEBUG_MODE from runtime arguments from imperialism_remake.base import switches if len(sys.argv) > 1 and sys.argv[1] == 'debug': switches.DEBUG_MODE = True if switches.DEBUG_MODE: print('debug mode is on') # redirect output to log files (will be overwritten at each start) Log_File = os.path.join(user_folder, 'remake.log') Error_File = os.path.join(user_folder, 'remake.error.log') # in debug mode print to the console instead if not switches.DEBUG_MODE: import codecs sys.stdout = codecs.open(Log_File, encoding='utf-8', mode='w') sys.stderr = codecs.open(Error_File, encoding='utf-8', mode='w') # import some base libraries import imperialism_remake.base.tools as tools # search for existing options file, if not existing, save it once (should just save an empty dictionary) Options_File = os.path.join(user_folder, 'options.info') if not os.path.exists(Options_File): tools.save_options(Options_File) # create single options object, load options and send a log message tools.load_options(Options_File) tools.log_info('options loaded from user folder ({})'.format(user_folder)) # special case of some desktop environments under Linux where full screen mode does not work well from imperialism_remake.base import constants # full screen support if tools.get_option(constants.Option.MAINWINDOW_FULLSCREEN_SUPPORTED): session = os.environ.get("DESKTOP_SESSION") if session and (session.startswith('ubuntu') or 'xfce' in session or session.startswith('xubuntu') or 'gnome' in session): tools.set_option(constants.Option.MAINWINDOW_FULLSCREEN_SUPPORTED, False) tools.log_warning('Desktop environment {} has problems with full screen mode. Will turn if off.'.format(session)) # we cannot have full screen without support if not tools.get_option(constants.Option.MAINWINDOW_FULLSCREEN_SUPPORTED): tools.set_option(constants.Option.MAINWINDOW_FULLSCREEN, False) # now we can safely assume that the environment is good to us # start server import multiprocessing # multiprocessing.freeze_support() multiprocessing.set_start_method('spawn') from imperialism_remake.server.server import ServerProcess server_process = ServerProcess() server_process.start() # start client, we will return when the program finishes from imperialism_remake.client.client import start_client start_client() # wait for server server_process.join() # save options tools.save_options(Options_File) tools.log_info('options saved') # report on unused resources if switches.DEBUG_MODE: tools.find_unused_resources() # good bye message tools.log_info('will exit soon - good bye')
def main(): """ Main entry point. Called from the script generated in setup.py and called when running this module with python. """ # TODO freeze_support might be needed for windows # (https://docs.python.org/3.6/library/multiprocessing.html#multiprocessing.freeze_support) # check if this is still the case, we are using pynsist (https://github.com/takluyver/pynsist) # for packaging on Windows # multiprocessing.freeze_support() # probably not with pynsist because it ships a full featured Python # guidelines at https://docs.python.org/3.6/library/multiprocessing.html#programming-guidelines multiprocessing.set_start_method('spawn') # test for minimal supported python version (3.5) required_version = (3, 5) if sys.version_info < required_version: raise RuntimeError('Python version must be {}.{} at least.'.format(*required_version)) # test for existence of PyQt5 try: from PyQt5 import QtCore # noqa: F401 except ImportError: raise RuntimeError('PyQt5 must be installed.') # test for minimal supported Qt version (5.5) if QtCore.QT_VERSION < 0x50500: raise RuntimeError('Qt version of PyQt5 must be 5.5 at least.') # Add the parent directory of the package directory to Python's search path. # This allows the import of the 'imperialism_remake' modules. # This is required at least for Linux distributions of Python3, since the current working # directory is not part of Python's search path by default. source_directory = os.path.realpath(os.path.join(os.path.abspath(os.path.dirname(__file__)), os.path.pardir)) if source_directory not in sys.path: sys.path.insert(0, source_directory) # import imperialism remake modules from imperialism_remake.lib import qt from imperialism_remake.base import constants, tools # fix PyQt5 exception eating qt.fix_pyqt5_exception_eating() # user folder user_folder = constants.get_user_directory() # if not existing, create user folder if not os.path.isdir(user_folder): os.mkdir(user_folder) # determine DEBUG_MODE from runtime arguments from imperialism_remake.base import switches args = get_arguments() switches.DEBUG_MODE = args.debug logger, log_queue, log_formatter, log_level, logger_cleanup = get_configured_logger(user_folder, switches.DEBUG_MODE) logger.info('user data stored in: {}'.format(user_folder)) # search for existing options file, if not existing, save it once (should just save an empty dictionary) options_file = os.path.join(user_folder, 'options.info') if not os.path.exists(options_file): tools.save_options(options_file) # create single options object, load options and send a log message tools.load_options(options_file) logger.info('options loaded from user folder (%s)', user_folder) # fix options: special case of some desktop environments under Linux where full screen mode does not work well # full screen support if tools.get_option(constants.Option.MAINWINDOW_FULLSCREEN_SUPPORTED): session = os.environ.get("DESKTOP_SESSION") # TODO: what exactly is the problem and how can we detect it (without guessing)? if (session and (session.startswith('ubuntu') or ('xfce' in session) or session.startswith('xubuntu') or ('gnome' in session))): tools.set_option(constants.Option.MAINWINDOW_FULLSCREEN_SUPPORTED, False) logger.warning('Desktop environment %s has problems with full screen mode. Will turn if off.', session) # options constraint: we cannot have full screen without support if not tools.get_option(constants.Option.MAINWINDOW_FULLSCREEN_SUPPORTED): tools.set_option(constants.Option.MAINWINDOW_FULLSCREEN, False) # start server from imperialism_remake.server.server import ServerProcess server_process = ServerProcess(log_queue, log_formatter, log_level) server_process.start() # start client, we will return when the client finishes from imperialism_remake.client.client import start_client start_client() # wait for server process to stop server_process.join() # save options tools.save_options(options_file) logger.info('options saved to file %s', options_file) # report on unused resources if switches.DEBUG_MODE: tools.find_unused_resources() # good bye message and shutdown logger logger.info('will exit soon - good bye') logger_cleanup()
def main(): """ Main entry point. Called from the script generated in setup.py and called when running this module with python. """ # TODO freeze_support might be needed for windows # (https://docs.python.org/3.6/library/multiprocessing.html#multiprocessing.freeze_support) # check if this is still the case, we are using pynsist (https://github.com/takluyver/pynsist) # for packaging on Windows # multiprocessing.freeze_support() # probably not with pynsist because it ships a full featured Python # guidelines at https://docs.python.org/3.6/library/multiprocessing.html#programming-guidelines multiprocessing.set_start_method('spawn') # test for minimal supported python version (3.5) required_version = (3, 5) if sys.version_info < required_version: raise RuntimeError( 'Python version must be {}.{} at least.'.format(*required_version)) # test for existence of PyQt5 try: from PyQt5 import QtCore # noqa: F401 except ImportError: raise RuntimeError('PyQt5 must be installed.') # test for minimal supported Qt version (5.5) if QtCore.QT_VERSION < 0x50500: raise RuntimeError('Qt version of PyQt5 must be 5.5 at least.') # Add the parent directory of the package directory to Python's search path. # This allows the import of the 'imperialism_remake' modules. # This is required at least for Linux distributions of Python3, since the current working # directory is not part of Python's search path by default. source_directory = os.path.realpath( os.path.join(os.path.abspath(os.path.dirname(__file__)), os.path.pardir)) if source_directory not in sys.path: sys.path.insert(0, source_directory) # import imperialism remake modules from imperialism_remake.lib import qt from imperialism_remake.base import constants, tools # fix PyQt5 exception eating qt.fix_pyqt5_exception_eating() # user folder user_folder = constants.get_user_directory() # if not existing, create user folder if not os.path.isdir(user_folder): os.mkdir(user_folder) # determine DEBUG_MODE from runtime arguments from imperialism_remake.base import switches args = get_arguments() switches.DEBUG_MODE = args.debug logger = logging.getLogger() logger.setLevel(logging.DEBUG if switches.DEBUG_MODE else logging.INFO) logger.info('user data stored in: {}'.format(user_folder)) # search for existing options file, if not existing, save it once (should just save an empty dictionary) options_file = os.path.join(user_folder, 'options.info') if not os.path.exists(options_file): tools.save_options(options_file) # create single options object, load options and send a log message tools.load_options(options_file) logger.info('options loaded from user folder (%s)', user_folder) # fix options: special case of some desktop environments under Linux where full screen mode does not work well # full screen support if tools.get_option(constants.Option.MAINWINDOW_FULLSCREEN_SUPPORTED): session = os.environ.get("DESKTOP_SESSION") # TODO: what exactly is the problem and how can we detect it (without guessing)? if (session and (session.startswith('ubuntu') or ('xfce' in session) or session.startswith('xubuntu') or ('gnome' in session))): tools.set_option(constants.Option.MAINWINDOW_FULLSCREEN_SUPPORTED, False) logger.warning( 'Desktop environment %s has problems with full screen mode. Will turn if off.', session) # options constraint: we cannot have full screen without support if not tools.get_option(constants.Option.MAINWINDOW_FULLSCREEN_SUPPORTED): tools.set_option(constants.Option.MAINWINDOW_FULLSCREEN, False) # start server from imperialism_remake.server.server_process import ServerProcess server_process = ServerProcess() server_process.start() logger.info('server process started (%s)', server_process.pid) # start client, we will return when the client finishes from imperialism_remake.client.client.client import start_client start_client() logger.info('client started') # wait for server process to stop server_process.join() # save options tools.save_options(options_file) logger.info('options saved to file %s', options_file) # report on unused resources if switches.DEBUG_MODE: tools.find_unused_resources() # good bye message and shutdown logger logger.info('will exit soon - good bye')
desktop = app.desktop() rect = desktop.screenGeometry() print('desktop geometry', rect, 'minimal required screen size', constants.MINIMAL_SCREEN_SIZE) # load global stylesheet to app with open(constants.GLOBAL_STYLESHEET_FILE, encoding='utf-8') as file: style_sheet = file.read() app.setStyleSheet(style_sheet) # set icon app.setWindowIcon(tools.load_ui_icon('window.icon.ico')) # main window main_window = QtWidgets.QWidget() # set geometry main_window.setGeometry(tools.get_option(constants.Option.MAINWINDOW_BOUNDS)) # set title main_window.setWindowTitle('Imperialism Remake') # show in full screen, maximized or normal if tools.get_option(constants.Option.MAINWINDOW_FULLSCREEN): main_window.setWindowFlags(main_window.windowFlags() | QtCore.Qt.FramelessWindowHint) main_window.showFullScreen() elif tools.get_option(constants.Option.MAINWINDOW_MAXIMIZED): main_window.showMaximized() else: main_window.show() # widget switcher widget_switcher = qt.WidgetSwitcher(main_window) do_nothing = lambda *args: None