from PySide6 import QtWidgets, QtCore, QtGui import util app = QtWidgets.QApplication([]) #TODO: Implement separate editor, terminal and main_window classes using Window as a parent class Window(QtWidgets.QMainWindow): def __init__(self, size=(640, 480), title="Concorde", on_resize=lambda event: None): super().__init__() self.setWindowTitle(title) self.resize(size[0], size[1]) self.__on_resize = on_resize def __del__(self): #TODO: whatever needs to be done here pass def set_title(self, title): self.setWindowTitle(title) def get_size(self): #TODO: implement util.warn("Not implemented!") return None def set_size(self, size_x, size_y): self.resize(size_x, size_y) def on_resize(self, function): self.__on_resize = function def update_menus(self, menu_dict, menu=None): # if not a sub menu if menu == None: menu = self.menuBar() menu.clear() #Looping through entire menu_dict for entry in menu_dict: # inactive or separator if menu_dict[entry] == None: # determine if entry is a separator or an inactive menu item if type(entry) == int: menu.addSeparator() else: menu_item = menu.addAction(entry) menu_item.setEnabled(False) # sub menus if type(menu_dict[entry]) == dict: submenu = menu.addMenu(entry) # recurse because sub menus may have sub menus self.update_menus(menu_dict[entry], menu=submenu) # ordinary menu entries if callable(menu_dict[entry]): menu_item = menu.addAction(entry) menu_item.triggered.connect(menu_dict[entry]) # Toolkit specific! Do not use outside gui_handler. def resizeEvent(self, event): self.__on_resize(event) class Editor(Window): def __init__(self, size=(640, 480)): super().__init__(size, "Editor") #TODO: Figure out a way to do the fucking line numbers #Text Editor self.text_edit = QtWidgets.QPlainTextEdit() self.text_edit.setFrameStyle(QtWidgets.QFrame.NoFrame) self.text_edit.setWordWrapMode(QtGui.QTextOption.NoWrap) self.tabs = QtWidgets.QTabWidget() self.tabs.addTab(self.text_edit, "untitled") self.setCentralWidget(self.tabs) class Message(QtWidgets.QMessageBox): def __init__(self, title, text): super().__init__() self.setWindowTitle(title) self.setText(text) self.setStandardButtons(QtWidgets.QMessageBox.Ok) self.exec() #TODO: This needs to run in a thread but Qt really doesn't want it to. There are two ways around this: # - create the QtWidgets.QApplication inside a thread and run all QT stuff inside that thread # - make a generic wrapper for window mainloop that will always run in the main thread while the actual main control flow of the program gets moved to another thread # There are some issues with these workarounds though; mainly that QT isn't thread safe. # I really want to keep QT running in its own thread because I want to retain the ability to arbitrarily spawn and manipulate windows while other windows are running. # Another issue that is probably easily worked around / fixed is that app.exec() will return once all running windows are closed. # Idea for a workaround for both: # Maybe Qt has scheduled events in which case a scheduled polling event could run a function inside the Qt thread that fetches commands and executes them. # This could work by passing (lambda) functions through a Communication object. #UPDATE: Tried implementing both approaches, neither worked. :( def fixme_window_mainloop_workaround_to_just_get_a_window_started_really_should_not_be_implemented_this_way_for_reasons_stated_in_the_comment_above_the_definition_of_this_function(): app.exec()