Refactor GUI to use Multi Document Interface
This commit is contained in:
@@ -1,42 +1,49 @@
|
||||
from PySide6.QtWidgets import QMainWindow, QWidget, QVBoxLayout, QTabWidget, QMenu, QTableView
|
||||
from PySide6.QtCore import Signal
|
||||
from PySide6.QtWidgets import QMainWindow, QWidget, QVBoxLayout, QTabWidget, QMenu, QTableView, QMdiSubWindow
|
||||
|
||||
from gui.model_config import KontorModelConfig
|
||||
from gui.table_model import KontorTableModel
|
||||
|
||||
|
||||
class ComicWindow(QWidget):
|
||||
class ComicWindow(QMdiSubWindow):
|
||||
closed = Signal()
|
||||
|
||||
def __init__(self, main_window):
|
||||
super().__init__()
|
||||
self.statusBar = main_window.statusBar
|
||||
self._main_window = main_window
|
||||
self.data_views = list()
|
||||
# self._create_menubar()
|
||||
self._main_window = main_window
|
||||
self.log = main_window.log
|
||||
self._init_gui()
|
||||
self.tick = main_window.tick
|
||||
self.cross = main_window.cross
|
||||
|
||||
def _init_gui(self):
|
||||
self.central_widget = QWidget()
|
||||
self.setWindowTitle("Comics")
|
||||
self.setWidget(QWidget())
|
||||
layout = QVBoxLayout()
|
||||
#self.central_widget.setLayout(parent_layout)
|
||||
self.tabs = QTabWidget()
|
||||
self.tabs.addTab(self.generate_data_tab("comic"), "Comics")
|
||||
self.tabs.addTab(self.generate_data_tab("publisher"), "Publisher")
|
||||
self.tabs.currentChanged.connect(self._tab_changed)
|
||||
# label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
layout.addWidget(self.tabs)
|
||||
self.setLayout(layout)
|
||||
# self.setCentralWidget(self.central_widget)
|
||||
self.setWidget(self.tabs)
|
||||
|
||||
# def _create_menubar(self):
|
||||
# menu_bar = self.menuBar()
|
||||
# comic_menu = QMenu("Comic")
|
||||
# menu_bar.addMenu(comic_menu)
|
||||
def closeEvent(self, event):
|
||||
self.closed.emit()
|
||||
super().closeEvent(event)
|
||||
self._main_window.remove_sub_window('comic')
|
||||
|
||||
def refresh(self):
|
||||
# self.log.info("refresh")
|
||||
self.data_views[self.tabs.currentIndex()].refresh()
|
||||
|
||||
def _tab_changed(self, tab_index):
|
||||
self.data_views[tab_index].refresh()
|
||||
|
||||
def update_status(self, message):
|
||||
self._main_window.update_status(message)
|
||||
|
||||
def generate_data_tab(self, table_name):
|
||||
data_tab = QWidget()
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from PySide6.QtGui import QAction, QIcon, QGuiApplication
|
||||
from PySide6.QtWidgets import QWidget, QVBoxLayout, QMenu, QMessageBox, QTabWidget, QTableView, QProgressBar
|
||||
from PySide6.QtWidgets import QWidget, QVBoxLayout, QMenu, QMessageBox, QTabWidget, QTableView, QProgressBar, QMdiArea
|
||||
from PySide6.QtWidgets import QLabel, QMainWindow
|
||||
from sqlalchemy import Engine
|
||||
from kontor_schema import KontorDB
|
||||
@@ -22,32 +22,39 @@ class MainWindow(QMainWindow):
|
||||
self.export_icon = QIcon("res/application-export.png")
|
||||
self.circle_icon = QIcon("res/arrow-circle-double.png")
|
||||
|
||||
self.data = []
|
||||
self.filter = {}
|
||||
self.kontor_db = KontorDB(engine, log)
|
||||
self.log = log
|
||||
self._subwindows = {}
|
||||
|
||||
self._setup_ui()
|
||||
|
||||
|
||||
#self.tabs = QTabWidget()
|
||||
#self.tabs.addTab(self.generate_data_tab("comic"), "Comics")
|
||||
#self.tabs.addTab(self.generate_data_tab("media_file"), "MediaFile")
|
||||
#self.tabs.currentChanged.connect(self._tab_changed)
|
||||
#label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
#parent_layout.addWidget(self.tabs)
|
||||
|
||||
self.setCentralWidget(self.central_widget)
|
||||
|
||||
def _setup_ui(self):
|
||||
self.setWindowTitle("Kontor")
|
||||
self.setMinimumSize(800, 500)
|
||||
self.setMinimumSize(1200, 800)
|
||||
self._create_actions()
|
||||
self.central_widget = QWidget()
|
||||
# parent_layout = QVBoxLayout()
|
||||
# self.central_widget.setLayout(parent_layout)
|
||||
self.mdi_area = QMdiArea(self.central_widget)
|
||||
self.mdi_area.setObjectName('mdi_area')
|
||||
self.setCentralWidget(self.central_widget)
|
||||
self._create_menubar()
|
||||
self._create_toolbars()
|
||||
self.status_progress = QProgressBar()
|
||||
self.progress_update = ProgressUpdate(self.status_progress)
|
||||
self._create_statusbar()
|
||||
|
||||
self.data = []
|
||||
self.filter = {}
|
||||
self.kontor_db = KontorDB(engine, log)
|
||||
self.log = log
|
||||
|
||||
self.comic_window = ComicWindow(self)
|
||||
self.central_widget = QWidget()
|
||||
parent_layout = QVBoxLayout()
|
||||
self.central_widget.setLayout(parent_layout)
|
||||
self.tabs = QTabWidget()
|
||||
self.tabs.addTab(self.generate_data_tab("comic"), "Comics")
|
||||
self.tabs.addTab(self.generate_data_tab("media_file"), "MediaFile")
|
||||
self.tabs.currentChanged.connect(self._tab_changed)
|
||||
#label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
parent_layout.addWidget(self.tabs)
|
||||
|
||||
self.setCentralWidget(self.central_widget)
|
||||
centerPoint = QGuiApplication.screens()[0].geometry().center()
|
||||
self.move(centerPoint - self.frameGeometry().center())
|
||||
|
||||
@@ -117,10 +124,26 @@ class MainWindow(QMainWindow):
|
||||
QMessageBox.about(self.central_widget, "Über Kontor", f"Python: 3.11\nKontor: 0.1.0")
|
||||
|
||||
def show_comic_window(self):
|
||||
if self.comic_window.isHidden():
|
||||
self.comic_window.show()
|
||||
if 'comic' not in self._subwindows:
|
||||
comic = ComicWindow(self)
|
||||
comic.closed.connect(self.sub_window_closed)
|
||||
self._subwindows['comic'] = comic
|
||||
self.mdi_area.addSubWindow(comic)
|
||||
comic.show()
|
||||
else:
|
||||
self.comic_window.hide()
|
||||
comic = self._subwindows.pop('comic')
|
||||
comic.close()
|
||||
self.mdi_area.removeSubWindow(comic)
|
||||
|
||||
def remove_sub_window(self, name: str):
|
||||
# self.log.info("remove subwindow %s", name)
|
||||
if name in self._subwindows:
|
||||
window = self._subwindows.pop(name)
|
||||
window.close()
|
||||
self.mdi_area.removeSubWindow(window)
|
||||
|
||||
def sub_window_closed(self):
|
||||
self.log.info("close subwindow")
|
||||
|
||||
def import_from_file(self):
|
||||
import_dlg = ImportKontorDialog(self)
|
||||
@@ -162,10 +185,17 @@ class MainWindow(QMainWindow):
|
||||
self.kontor_db.check_files()
|
||||
|
||||
def refresh(self):
|
||||
self.data[self.tabs.currentIndex()].refresh()
|
||||
self.log.info("refresh")
|
||||
for (_, window) in self._subwindows.items():
|
||||
window.refresh()
|
||||
# def refresh(self):
|
||||
# self.data[self.tabs.currentIndex()].refresh()
|
||||
|
||||
def _tab_changed(self, tab_index):
|
||||
self.data[tab_index].refresh()
|
||||
# def _tab_changed(self, tab_index):
|
||||
# self.data[tab_index].refresh()
|
||||
|
||||
def update_status(self, message, timeout=3000):
|
||||
self.statusBar.showMessage(message, timeout=timeout)
|
||||
|
||||
def generate_data_tab(self, table_name):
|
||||
data_tab = QWidget()
|
||||
@@ -181,3 +211,4 @@ class MainWindow(QMainWindow):
|
||||
layout.addWidget(table_view)
|
||||
model.refresh()
|
||||
return data_tab
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from PySide6.QtWidgets import QHBoxLayout, QCheckBox
|
||||
from PySide6.QtWidgets import QHBoxLayout, QCheckBox, QMdiSubWindow
|
||||
from kontor_schema import KontorDB
|
||||
|
||||
|
||||
@@ -8,15 +8,23 @@ class KontorModelConfig:
|
||||
self.header = {}
|
||||
self.filter = {}
|
||||
self.main_window = main_window
|
||||
self.log = main_window.log
|
||||
self._table_name = table_name
|
||||
self.kontor_db = kontor_db
|
||||
self.get_table_config()
|
||||
|
||||
def __str__(self):
|
||||
return f"KontorModelConfig({self._table_name})"
|
||||
|
||||
def get_table_config(self):
|
||||
# self.log.info("get_table_config %s", self)
|
||||
self.header = self.kontor_db.get_column_meta_data(self._table_name)
|
||||
self.filter = self.kontor_db.get_filters(self._table_name)
|
||||
# self.log.info("headers: %s", self.header)
|
||||
# self.log.info("%s filters: %s", self, self.filter)
|
||||
|
||||
def filters(self) -> dict:
|
||||
# self.log.info("%s filters: %s", self, self.filter)
|
||||
_filters = {}
|
||||
# print(self.filter["download"].isChecked())
|
||||
for column, filter_info in self.filter.items():
|
||||
@@ -24,18 +32,17 @@ class KontorModelConfig:
|
||||
if filter_info['widget'].isChecked():
|
||||
_filters[column] = True
|
||||
# print(f"{filter_rule=}")
|
||||
# self.log.info("filters -> %s", _filters)
|
||||
return _filters
|
||||
|
||||
def get_data(self) -> list:
|
||||
# data = self.kontor_db.get_data(self._table_name, self.header, self.get_filter())
|
||||
# data.clear()
|
||||
# self.log.info("get_data")
|
||||
data = self.kontor_db.data(self._table_name, self.header, self.filters())
|
||||
# print(f"KontorModelConfig.get_data: {len(data)}")
|
||||
# comics = self.kontor_db.session.query(Comic).all()
|
||||
# print(f'{len(comics)} Comics loaded')
|
||||
# self.log.info("get_data: %d %s", len(data), data)
|
||||
return data
|
||||
|
||||
def get_filter_layout(self) -> QHBoxLayout:
|
||||
# self.log.info("get_filter_layout: %s", self.filter)
|
||||
filter_layout = QHBoxLayout()
|
||||
for column, filter_info in self.filter.items():
|
||||
filter_checkbox = QCheckBox()
|
||||
@@ -44,4 +51,5 @@ class KontorModelConfig:
|
||||
self.filter[column]['widget'] = filter_checkbox
|
||||
filter_layout.addWidget(filter_checkbox)
|
||||
filter_layout.addStretch()
|
||||
# self.log.info("get_filter_layout: %s", self.filter)
|
||||
return filter_layout
|
||||
|
||||
@@ -13,8 +13,13 @@ class KontorTableModel(QAbstractTableModel):
|
||||
self._main_window = model_config.main_window
|
||||
self._config = model_config
|
||||
self._data = []
|
||||
self.log = model_config.log
|
||||
|
||||
def __str__(self):
|
||||
return f"KontorTableModel({self._config})"
|
||||
|
||||
def refresh(self):
|
||||
# self.log.info("refresh")
|
||||
data = self._config.get_data()
|
||||
count = 0
|
||||
# print(data)
|
||||
@@ -27,9 +32,10 @@ class KontorTableModel(QAbstractTableModel):
|
||||
# print(data)
|
||||
# print(self._data)
|
||||
self.layoutChanged.emit()
|
||||
self._main_window.statusBar.showMessage(f"{count} Einträge geladen", 3000)
|
||||
self._main_window.update_status(f"{count} Einträge geladen")
|
||||
|
||||
def rowCount(self, parent=QModelIndex()):
|
||||
# self.log.info("rowCount %s: %d", self, len(self._data))
|
||||
# The length of the outer list.
|
||||
if self._data is None:
|
||||
return 0
|
||||
@@ -53,53 +59,51 @@ class KontorTableModel(QAbstractTableModel):
|
||||
return value
|
||||
if isinstance(value, bytes):
|
||||
if value == b'\x01':
|
||||
return self._main_window.tick
|
||||
return self._config.main_window.tick
|
||||
else:
|
||||
return self._main_window.cross
|
||||
return self._config.main_window.cross
|
||||
if isinstance(value, int):
|
||||
# print('{}:: {}: {}'.format(index, value, type(value)))
|
||||
if value == 1:
|
||||
return self._main_window.tick
|
||||
return self._config.main_window.tick
|
||||
else:
|
||||
return self._main_window.cross
|
||||
return self._config.main_window.cross
|
||||
if isinstance(value, bool):
|
||||
if value:
|
||||
return self._main_window.tick
|
||||
return self._config.main_window.tick
|
||||
else:
|
||||
return self._main_window.cross
|
||||
return self._config.main_window.cross
|
||||
return str(value)
|
||||
if role == Qt.ItemDataRole.DecorationRole:
|
||||
if isinstance(value, bytes):
|
||||
if value == b'\x01':
|
||||
return self._main_window.tick
|
||||
return self._config.main_window.tick
|
||||
else:
|
||||
return self._main_window.cross
|
||||
return self._config.main_window.cross
|
||||
if isinstance(value, int):
|
||||
if value == 1:
|
||||
return self._main_window.tick
|
||||
return self._config.main_window.tick
|
||||
else:
|
||||
return self._main_window.cross
|
||||
return self._config.main_window.cross
|
||||
if isinstance(value, bool):
|
||||
if value:
|
||||
return self._main_window.tick
|
||||
return self._config.main_window.tick
|
||||
else:
|
||||
return self._main_window.cross
|
||||
return self._config.main_window.cross
|
||||
|
||||
def columnCount(self, index=QModelIndex()):
|
||||
# The following takes the first sub-list, and returns
|
||||
# the length (only works if all rows are an equal length)
|
||||
# print(f"Header count: {len(self._config.get_header())}")
|
||||
# self.log.info("rowCount %s: %d", self, len(self._config.header))
|
||||
return len(self._config.header)
|
||||
|
||||
def setData(self, index, value, role: int) -> bool:
|
||||
print(index, role)
|
||||
# print(index, role)
|
||||
if role == Qt.ItemDataRole.EditRole:
|
||||
self._data[index.row()][index.column()] = value
|
||||
print(self._data[index.row()][index.column()])
|
||||
# print(self._data[index.row()][index.column()])
|
||||
self.dataChanged.emit(index, index)
|
||||
return True
|
||||
if role == Qt.ItemDataRole.CheckStateRole:
|
||||
print("role == Qt.ItemDataRole.CheckStateRole")
|
||||
# print("role == Qt.ItemDataRole.CheckStateRole")
|
||||
checked = value == Qt.CheckState.Checked
|
||||
self._data[index.row()][index.column()] = checked
|
||||
return False
|
||||
|
||||
Reference in New Issue
Block a user