def __init__(self): super(Model, self).__init__() self.current_file = None self.session = None # Setting up SQL relevant stuff self.wahl_nummer = 1 self.undostack = QUndoStack()
def __init__(self, parent=None): super().__init__(parent) self.undo_stack = QUndoStack() self.statusBar() self.view = Ui_MainWindow() self.view.setupUi(self) self.view.tableView.setSortingEnabled(False) self.view.tableView.setItemDelegate(ItemDelegate(self.undo_stack, self.set_undo_redo_text)) self.filename = None self.table_model = CSVTableModel(self, datalist=[], header=[]) self.view.actionConnect.setEnabled(True) self.view.actionDisconnect.setEnabled(False) self.view.actionInsert.setEnabled(False) self.view.actionReceive.setEnabled(False) self.view.actionCalculate_Predictions.setEnabled(False) self.view.actionAbout_Qt.triggered.connect(self.about_qt) self.view.actionAbout.triggered.connect(self.about) self.view.actionConnect.triggered.connect(self.connect) self.view.actionDisconnect.triggered.connect(self.disconnect) self.view.actionInsert.triggered.connect(self.insert) self.view.actionReceive.triggered.connect(self.receive) self.view.actionCalculate_Predictions.triggered.connect(self.calculate_predictions) self.view.actionUndo.triggered.connect(self.undo) self.view.actionRedo.triggered.connect(self.redo) self.view.actionCopy.triggered.connect(self.copy) self.view.actionPaste.triggered.connect(self.paste) self.view.actionInsert_Row_s.triggered.connect(self.insert_rows) self.view.actionDuplicate_Row_s.triggered.connect(self.duplicate_rows) self.view.actionRemove_Row_s.triggered.connect(self.remove_rows) self.view.actionNew.triggered.connect(self.new) self.view.actionOpen.triggered.connect(self.open) self.view.actionSave.triggered.connect(self.save) self.view.actionSave_as.triggered.connect(self.save_as) self.db = None
def __init__(self, parent=None): super().__init__(parent) self.undoStack = QUndoStack() self.view = Ui_MainWindow() self.view.setupUi(self) self.view.tableView.setSortingEnabled(True) self.view.tableView.setItemDelegate(ItemDelegate(self.undoStack, self.set_undo_redo_text)) self.filename = None self.table_model = CSVTableModel(datalist=[], header=[], parent=self) self.connect_elements() try: self.db = DBAccess(DBConfig.database, DBConfig.username, DBConfig.password, DBConfig.wahltermin) except Exception as e: print(e) Message.error("Database Error", "Error while trying to establish a database connection.")
def __init__(self, parent=None): super().__init__(parent) self.undoStack = QUndoStack() self.db = DBConnection("172.16.6.137", "root", "password", "wahl") self.gui = Ui_MainWindow() self.gui.setupUi(self) self.gui.actionOpen.triggered.connect(self.open_file) self.gui.actionSave.triggered.connect(self.save_file) self.gui.actionSave_as.triggered.connect(self.save_file_as) self.gui.actionNew.triggered.connect(self.new_file) self.gui.actionCopy.triggered.connect(self.copy_cs) self.gui.actionAdd_Row.triggered.connect(self.add_rows) self.gui.actionSave_DB.triggered.connect(self.open_save_db) self.gui.actionOpen_DB.triggered.connect(self.open_load_db) self.gui.actionPaste.triggered.connect(self.paste) self.gui.actionCut.triggered.connect(self.cut) self.gui.actionDelete_Row.triggered.connect(self.remove_rows) self.gui.actionDuplicate_Row.triggered.connect(self.duplicate) self.gui.actionUndo.triggered.connect(self.undo) self.gui.actionRedo.triggered.connect(self.redo) self.gui.actionCreate_Prediction.triggered.connect(self.open_create_pred) self.gui.actionShow_Prediction.triggered.connect(self.open_choose_pred) self.gui.tableView.setSortingEnabled(True) self.gui.tableView.setItemDelegate(ItemDelegate(self.undoStack, self.set_unrdo_text)) self.tbm = DictTableModel(data=[], header=[], parent=self) self.sdb_dialog = SaveToDBDialog(self) self.ldb_dialog = LoadFromDBDialog(self) self.create_pred_dialog = CreatePredDialog(self) self.choose_pred_dialog = ChoosePredDialog(self) self.show_pred_dialog = ShowPredDialog(self) self.file = "."
class WahlAnalyse(QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.undoStack = QUndoStack() self.db = DBConnection("172.16.6.137", "root", "password", "wahl") self.gui = Ui_MainWindow() self.gui.setupUi(self) self.gui.actionOpen.triggered.connect(self.open_file) self.gui.actionSave.triggered.connect(self.save_file) self.gui.actionSave_as.triggered.connect(self.save_file_as) self.gui.actionNew.triggered.connect(self.new_file) self.gui.actionCopy.triggered.connect(self.copy_cs) self.gui.actionAdd_Row.triggered.connect(self.add_rows) self.gui.actionSave_DB.triggered.connect(self.open_save_db) self.gui.actionOpen_DB.triggered.connect(self.open_load_db) self.gui.actionPaste.triggered.connect(self.paste) self.gui.actionCut.triggered.connect(self.cut) self.gui.actionDelete_Row.triggered.connect(self.remove_rows) self.gui.actionDuplicate_Row.triggered.connect(self.duplicate) self.gui.actionUndo.triggered.connect(self.undo) self.gui.actionRedo.triggered.connect(self.redo) self.gui.actionCreate_Prediction.triggered.connect(self.open_create_pred) self.gui.actionShow_Prediction.triggered.connect(self.open_choose_pred) self.gui.tableView.setSortingEnabled(True) self.gui.tableView.setItemDelegate(ItemDelegate(self.undoStack, self.set_unrdo_text)) self.tbm = DictTableModel(data=[], header=[], parent=self) self.sdb_dialog = SaveToDBDialog(self) self.ldb_dialog = LoadFromDBDialog(self) self.create_pred_dialog = CreatePredDialog(self) self.choose_pred_dialog = ChoosePredDialog(self) self.show_pred_dialog = ShowPredDialog(self) self.file = "." def open_file(self): self.file = QFileDialog.getOpenFileName(self, "Choose File", filter="CSV-File (*.csv)")[0] if self.file != '': data, header = CSVUtil.read(self.file) self.tbm.set_data(data, header) self.gui.tableView.reset() self.gui.tableView.setModel(self.tbm) def save_file(self): if self.file != '' and self.file is not None: CSVUtil.write(self.file, self.tbm.get_data()) def save_file_as(self): self.file = QFileDialog.getSaveFileName(self, "CSV-Datei speichern", dir=self.file, filter="CSV-Datei (*.csv)")[ 0] if self.file != '': self.save_file() def new_file(self): self.file = "." self.tbm.set_data([], []) self.gui.tableView.reset() self.gui.tableView.setModel(self.tbm) self.undoStack.clear() self.set_unrdo_text() def copy_cs(self): if len(self.gui.tableView.selectionModel().selectedIndexes()) == 0: return clipboard = QApplication.clipboard() selected_index = self.gui.tableView.selectionModel().selectedIndexes()[0] selected_text = str(self.tbm.data(selected_index)) clipboard.setText(selected_text) def save_data_db(self, date): self.db.write_data(self.tbm.get_data(), date) def load_data_db(self, date): data, header = self.db.read_data(date) self.tbm.set_data(data, header) self.gui.tableView.reset() self.gui.tableView.setModel(self.tbm) self.undoStack.clear() self.set_unrdo_text() def create_prediction(self, termin, time): self.db.create_prediction(termin, time) def open_save_db(self): self.setDisabled(True) self.sdb_dialog.setEnabled(True) self.sdb_dialog.show() def open_load_db(self): self.ldb_dialog.update_dates(self.db.get_termine()) self.setDisabled(True) self.ldb_dialog.setEnabled(True) self.ldb_dialog.show() def open_create_pred(self): self.create_pred_dialog.update_dates(self.db.get_termine()) self.setDisabled(True) self.create_pred_dialog.setEnabled(True) self.create_pred_dialog.show() def open_choose_pred(self): self.choose_pred_dialog.update_predictions(self.db.get_predictions()) self.setDisabled(True) self.choose_pred_dialog.setEnabled(True) self.choose_pred_dialog.show() def show_prediction(self, date, time): data, header = self.db.get_prediction_data(date, time) self.show_pred_dialog.update_prediction(data, header, date, time) self.setDisabled(True) self.show_pred_dialog.setEnabled(True) self.show_pred_dialog.show() def set_unrdo_text(self): undo = "Undo" redo = "Redo" undo_txt = self.undoStack.undoText() redo_txt = self.undoStack.redoText() if undo_txt: undo += " \"" + undo_txt + "\"" if redo_txt: redo += " \"" + redo_txt + "\"" self.gui.actionUndo.setText(undo) self.gui.actionRedo.setText(redo) def get_sel_indexes(self): sel_indexes = self.gui.tableView.selectedIndexes() if sel_indexes: return [index for index in sel_indexes if not index.column()] def get_sel(self): sel_indexes = self.get_sel_indexes() if not sel_indexes: return self.tbm.rowCount(self), 1 first_sel_index = sel_indexes[0] sel_indexes = self.get_sel_indexes() if not first_sel_index or not first_sel_index.isValid(): return False startingrow = first_sel_index.row() return startingrow, len(sel_indexes) def remove_rows(self): if len(self.tbm.get_data()) == 0: return start, amount = self.get_sel() if start != len(self.tbm.get_data()): self.undoStack.beginMacro("Remove Rows") self.undoStack.push(RemoveRowsCommand(self.tbm, start, amount)) self.undoStack.endMacro() self.set_unrdo_text() def add_rows(self): if len(self.tbm.get_header()) == 0: return start, amount = self.get_sel() self.undoStack.beginMacro("Add Row") self.undoStack.push(InsertRowsCommand(self.tbm, start, 1)) self.undoStack.endMacro() self.set_unrdo_text() def paste(self): if len(self.gui.tableView.selectionModel().selectedIndexes()) == 0: return clipboard = QApplication.clipboard() index = self.gui.tableView.selectionModel().selectedIndexes()[0] command = EditCommand(self.tbm, index) command.newVal(str(clipboard.text())) self.undoStack.beginMacro("Paste") self.undoStack.push(command) self.undoStack.endMacro() self.set_unrdo_text() self.gui.tableView.reset() def cut(self): self.copy() index = self.gui.tableView.selectionModel().selectedIndexes()[0] command = EditCommand(self.tbm, index) command.newVal("") self.undoStack.beginMacro("Cut") self.undoStack.push(command) self.undoStack.endMacro() self.set_unrdo_text() self.gui.tableView.reset() def duplicate(self): if len(self.gui.tableView.selectionModel().selectedIndexes()) == 0: return start, amount = self.get_sel() self.undoStack.beginMacro("Duplicate Row") self.undoStack.push(DuplicateRowCommand(self.tbm, start)) self.undoStack.endMacro() self.set_unrdo_text() self.gui.tableView.reset() def undo(self): self.undoStack.undo() self.set_unrdo_text() self.gui.tableView.reset() def redo(self): self.undoStack.redo() self.set_unrdo_text() self.gui.tableView.reset()
class CSVTableController(QtGui.QMainWindow): # noinspection PyCompatibility def __init__(self, parent=None): super().__init__(parent) self.undo_stack = QUndoStack() self.statusBar() self.view = Ui_MainWindow() self.view.setupUi(self) self.view.tableView.setSortingEnabled(False) self.view.tableView.setItemDelegate(ItemDelegate(self.undo_stack, self.set_undo_redo_text)) self.filename = None self.table_model = CSVTableModel(self, datalist=[], header=[]) self.view.actionConnect.setEnabled(True) self.view.actionDisconnect.setEnabled(False) self.view.actionInsert.setEnabled(False) self.view.actionReceive.setEnabled(False) self.view.actionCalculate_Predictions.setEnabled(False) self.view.actionAbout_Qt.triggered.connect(self.about_qt) self.view.actionAbout.triggered.connect(self.about) self.view.actionConnect.triggered.connect(self.connect) self.view.actionDisconnect.triggered.connect(self.disconnect) self.view.actionInsert.triggered.connect(self.insert) self.view.actionReceive.triggered.connect(self.receive) self.view.actionCalculate_Predictions.triggered.connect(self.calculate_predictions) self.view.actionUndo.triggered.connect(self.undo) self.view.actionRedo.triggered.connect(self.redo) self.view.actionCopy.triggered.connect(self.copy) self.view.actionPaste.triggered.connect(self.paste) self.view.actionInsert_Row_s.triggered.connect(self.insert_rows) self.view.actionDuplicate_Row_s.triggered.connect(self.duplicate_rows) self.view.actionRemove_Row_s.triggered.connect(self.remove_rows) self.view.actionNew.triggered.connect(self.new) self.view.actionOpen.triggered.connect(self.open) self.view.actionSave.triggered.connect(self.save) self.view.actionSave_as.triggered.connect(self.save_as) self.db = None def show_window(self): self.setEnabled(True) self.show() self.raise_() def update_table_model(self, data, header): self.table_model.set_list(data, header) self.view.tableView.reset() self.view.tableView.setModel(self.table_model) def set_undo_redo_text(self): undo = "Undo" redo = "Redo" undo_text = self.undo_stack.undoText() redo_text = self.undo_stack.redoText() if undo_text: undo += " \"" + undo_text + "\"" if redo_text: redo += " \"" + redo_text + "\"" self.view.actionUndo.setText(undo) self.view.actionRedo.setText(redo) def get_selection(self): zero_column_selected_indexes = self.get_zero_column_selected_indexes() if not zero_column_selected_indexes: return self.table_model.rowCount(self), 1 first_zero_column_selected_index = zero_column_selected_indexes[0] zero_column_selected_indexes = self.get_zero_column_selected_indexes() if not first_zero_column_selected_index or not first_zero_column_selected_index.isValid(): return False startingrow = first_zero_column_selected_index.row() return startingrow, len(zero_column_selected_indexes) def get_zero_column_selected_indexes(self): selected_indexes = self.view.tableView.selectedIndexes() if not selected_indexes: return return [index for index in selected_indexes if not index.column()] def about_qt(self): QtGui.qApp.aboutQt() def about(self): self.about = AboutWindow() self.about.show() def connect(self): QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) connection_string = 'mysql+mysqldb://{username}:{password}@{host}/{database}'.format(username=USERNAME, password=PASSWORD, host=HOST, database=DATABASE) try: if self.db is None: self.db = DatabaseManager(connectionstring=connection_string, electiondate="2015-10-11") self.statusBar().showMessage("Successfully connected to database") self.view.actionConnect.setEnabled(False) self.view.actionDisconnect.setEnabled(True) self.view.actionInsert.setEnabled(True) self.view.actionReceive.setEnabled(True) self.view.actionCalculate_Predictions.setEnabled(True) except: QtGui.QMessageBox.critical(self, "Connection Error", "Error connecting to Database:\n" + sys.exc_info()[0], QMessageBox.Close) QtGui.QApplication.restoreOverrideCursor() def disconnect(self): QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) if self.db is not None: self.db.close() self.db = None self.view.actionConnect.setEnabled(True) self.view.actionDisconnect.setEnabled(False) self.view.actionInsert.setEnabled(False) self.view.actionReceive.setEnabled(False) self.view.actionCalculate_Predictions.setEnabled(False) self.statusBar().showMessage("Successfully disconnected from database") QtGui.QApplication.restoreOverrideCursor() def insert(self): if self.filename is None or len(self.table_model.get_list()) == 0: self.statusBar().showMessage("You need to have some data to insert") return try: current_list = self.table_model.get_list() self.db.write(current_list) except Exception as e: print(e) self.statusBar().showMessage("Error while accessing the database.") def receive(self): try: data = self.db.load() self.table_model.set_list(data) self.update_table_model(self.table_model.get_list(), self.table_model.get_header()) except Exception as e: print(e) self.statusBar().showMessage("Error while accessing the database.") def calculate_predictions(self): """ Cudos an Rene Hollander """ projection_data = self.db.create_projection() print("Hochrechnung:") for key, value in projection_data.items(): print(key + ": " + str(value)) print("\n") ind = numpy.arange(len(projection_data)) width = 0.5 plt.bar(ind, list(projection_data.values()), width, color='r') plt.ylabel('%') plt.xlabel('Parteien') plt.title('Wien Wahl Hochrechnung') plt.xticks(ind + width / 2, list(projection_data.keys())) plt.yticks(numpy.arange(0, 61, 5)) plt.show() def undo(self): self.undo_stack.undo() self.set_undo_redo_text() self.view.tableView.reset() def redo(self): self.undo_stack.redo() self.set_undo_redo_text() self.view.tableView.reset() def copy(self): if len(self.view.tableView.selectionModel().selectedIndexes()) == 0: return clipboard = QApplication.clipboard() selected_index = self.view.tableView.selectionModel().selectedIndexes()[0] selected_text = str(self.table_model.data(selected_index)) clipboard.setText(selected_text) def paste(self): if len(self.view.tableView.selectionModel().selectedIndexes()) == 0: return clipboard = QApplication.clipboard() index = self.view.tableView.selectionModel().selectedIndexes()[0] command = EditCommand(self.table_model, index) command.newValue(str(clipboard.text())) self.undo_stack.beginMacro("Paste") self.undo_stack.push(command) self.undo_stack.endMacro() self.set_undo_redo_text() self.view.tableView.reset() def insert_rows(self): if len(self.table_model.get_header()) == 0: self.statusBar().showMessage("Adding rows to an empty table without a header is not possible.") return start, amount = self.get_selection() self.undo_stack.beginMacro("Add Row") self.undo_stack.push(InsertRowsCommand(self.table_model, start, 1)) self.undo_stack.endMacro() self.set_undo_redo_text() def duplicate_rows(self): if len(self.view.tableView.selectionModel().selectedIndexes()) == 0: self.statusBar().showMessage("You must select the first column of the row you want to duplicate") return start, amount = self.get_selection() self.undo_stack.beginMacro("Duplicate Row") self.undo_stack.push(DuplicateRowCommand(self.table_model, start)) self.undo_stack.endMacro() self.set_undo_redo_text() self.view.tableView.reset() def remove_rows(self): if len(self.table_model.get_list()) == 0: self.statusBar().showMessage("WARNING: Removing rows from an empty table is not possible") return start, amount = self.get_selection() if start != len(self.table_model.get_list()): self.undo_stack.beginMacro("Remove Row(s)") self.undo_stack.push(RemoveRowsCommand(self.table_model, start, amount)) self.undo_stack.endMacro() self.set_undo_redo_text() else: self.statusBar().showMessage("WARNING: You need to choose the rows you want to remove by selecting the cells in the " "first column") def new(self): if self.filename is not None: save = self.show_new_file_dialog() if(save): self.save() self.filename = None self.table_model.set_list([], []) else: self.filename = None self.table_model.set_list([], []) else: self.filename = None self.table_model.set_list([], []) def show_append_override_dialog(self): msgBox = QtGui.QMessageBox() msgBox.setWindowTitle("Append or Override") msgBox.setText("Append or override the current entries?") msgBox.addButton("Append", QtGui.QMessageBox.YesRole) msgBox.addButton("Override", QtGui.QMessageBox.NoRole) return msgBox.exec_() def show_new_file_dialog(self): msgBox = QtGui.QMessageBox() msgBox.setWindowTitle("New file") msgBox.setText("Do you want to save first?") msgBox.addButton("Yes", QtGui.QMessageBox.YesRole) msgBox.addButton("No", QtGui.QMessageBox.NoRole) return msgBox.exec_() def open(self): try: fileName = QFileDialog.getOpenFileName(self, self.tr("Open CSV File"), os.getcwd(), self.tr("CSV Files (*.csv)"))[0] if fileName is not None and fileName is not "": append_or_override = False if self.filename is not None: append_or_override = self.show_append_override_dialog() self.filename = fileName self.table_model.open(self.filename, clear=append_or_override) self.undo_stack.clear() self.set_undo_redo_text() self.update_table_model(self.table_model.get_list(), self.table_model.get_header()) except FileNotFoundError: QtGui.QMessageBox.critical(self, "Read Error", "Error reading CSV File:\nFile \"" + self.filename + "\" not found!", QtGui.QMessageBox.Close) except csv.Error: QtGui.QMessageBox.critical(self, "Read Error", "Error reading CSV File:\n File is not an valid CSV File!", QtGui.QMessageBox.Close) except: QtGui.QMessageBox.critical(self, "Read Error", "Error reading CSV File:\nAn unknown Error occured!", QtGui.QMessageBox.Close) raise def save(self): if self.filename is not None and self.filename is not "": self.table_model.save(self.filename) else: fileName = QFileDialog.getSaveFileName(self, caption="Save CSV File", dir=os.getcwd(), filter="CSV Files (*.csv)")[0] if fileName is not None and fileName is not "": self.table_model.save(fileName) def save_as(self): fileName = QFileDialog.getSaveFileName(self, caption="Save CSV File", dir=os.getcwd(), filter="CSV Files (*.csv)")[0] if fileName is not None and fileName is not "": self.table_model.save(fileName)
class CSVTableController(QtGui.QMainWindow): # noinspection PyCompatibility def __init__(self, parent=None): super().__init__(parent) self.undo_stack = QUndoStack() self.statusBar() self.view = Ui_MainWindow() self.view.setupUi(self) self.view.tableView.setSortingEnabled(False) self.view.tableView.setItemDelegate(ItemDelegate(self.undo_stack, self.set_undo_redo_text)) self.filename = None self.table_model = CSVTableModel(self, datalist=[], header=[]) self.view.actionConnect.setEnabled(True) self.view.actionDisconnect.setEnabled(False) self.view.actionInsert.setEnabled(False) self.view.actionReceive.setEnabled(False) self.view.actionCalculate_Predictions.setEnabled(False) self.view.actionAbout_Qt.triggered.connect(self.about_qt) self.view.actionAbout.triggered.connect(self.about) self.view.actionConnect.triggered.connect(self.connect) self.view.actionDisconnect.triggered.connect(self.disconnect) self.view.actionInsert.triggered.connect(self.insert) self.view.actionReceive.triggered.connect(self.receive) self.view.actionCalculate_Predictions.triggered.connect(self.calculate_predictions) self.view.actionUndo.triggered.connect(self.undo) self.view.actionRedo.triggered.connect(self.redo) self.view.actionCopy.triggered.connect(self.copy) self.view.actionPaste.triggered.connect(self.paste) self.view.actionInsert_Row_s.triggered.connect(self.insert_rows) self.view.actionDuplicate_Row_s.triggered.connect(self.duplicate_rows) self.view.actionRemove_Row_s.triggered.connect(self.remove_rows) self.view.actionNew.triggered.connect(self.new) self.view.actionOpen.triggered.connect(self.open) self.view.actionSave.triggered.connect(self.save) self.view.actionSave_as.triggered.connect(self.save_as) self.db = None def show_window(self): self.setEnabled(True) self.show() self.raise_() def update_table_model(self, data, header): self.table_model.set_list(data, header) self.view.tableView.reset() self.view.tableView.setModel(self.table_model) def set_undo_redo_text(self): undo = "Undo" redo = "Redo" undo_text = self.undo_stack.undoText() redo_text = self.undo_stack.redoText() if undo_text: undo += ' "' + undo_text + '"' if redo_text: redo += ' "' + redo_text + '"' self.view.actionUndo.setText(undo) self.view.actionRedo.setText(redo) def get_selection(self): zero_column_selected_indexes = self.get_zero_column_selected_indexes() if not zero_column_selected_indexes: return self.table_model.rowCount(self), 1 first_zero_column_selected_index = zero_column_selected_indexes[0] zero_column_selected_indexes = self.get_zero_column_selected_indexes() if not first_zero_column_selected_index or not first_zero_column_selected_index.isValid(): return False startingrow = first_zero_column_selected_index.row() return startingrow, len(zero_column_selected_indexes) def get_zero_column_selected_indexes(self): selected_indexes = self.view.tableView.selectedIndexes() if not selected_indexes: return return [index for index in selected_indexes if not index.column()] def about_qt(self): QtGui.qApp.aboutQt() def about(self): self.about = AboutWindow() self.about.show() def connect(self): QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) connection_string = "mysql+mysqldb://{username}:{password}@{host}/{database}".format( username=USERNAME, password=PASSWORD, host=HOST, database=DATABASE ) try: if self.db is None: self.db = DatabaseManager(connectionstring=connection_string, electiondate="2015-10-11") self.statusBar().showMessage("Successfully connected to database") self.view.actionConnect.setEnabled(False) self.view.actionDisconnect.setEnabled(True) self.view.actionInsert.setEnabled(True) self.view.actionReceive.setEnabled(True) self.view.actionCalculate_Predictions.setEnabled(True) except: QtGui.QMessageBox.critical( self, "Connection Error", "Error connecting to Database:\n" + sys.exc_info()[0], QMessageBox.Close ) QtGui.QApplication.restoreOverrideCursor() def disconnect(self): QtGui.QApplication.setOverrideCursor(QtCore.Qt.WaitCursor) if self.db is not None: self.db.close() self.db = None self.view.actionConnect.setEnabled(True) self.view.actionDisconnect.setEnabled(False) self.view.actionInsert.setEnabled(False) self.view.actionReceive.setEnabled(False) self.view.actionCalculate_Predictions.setEnabled(False) self.statusBar().showMessage("Successfully disconnected from database") QtGui.QApplication.restoreOverrideCursor() def insert(self): if self.filename is None or len(self.table_model.get_list()) == 0: self.statusBar().showMessage("You need to have some data to insert") return try: current_list = self.table_model.get_list() self.db.write(current_list) except Exception as e: print(e) self.statusBar().showMessage("Error while accessing the database.") def receive(self): try: data = self.db.load() self.table_model.set_list(data) self.update_table_model(self.table_model.get_list(), self.table_model.get_header()) except Exception as e: print(e) self.statusBar().showMessage("Error while accessing the database.") def calculate_predictions(self): """ Cudos an Rene Hollander """ projection_data = self.db.create_projection() print("Hochrechnung:") for key, value in projection_data.items(): print(key + ": " + str(value)) print("\n") ind = numpy.arange(len(projection_data)) width = 0.5 plt.bar(ind, list(projection_data.values()), width, color="r") plt.ylabel("%") plt.xlabel("Parteien") plt.title("Wien Wahl Hochrechnung") plt.xticks(ind + width / 2, list(projection_data.keys())) plt.yticks(numpy.arange(0, 61, 5)) plt.show() def undo(self): self.undo_stack.undo() self.set_undo_redo_text() self.view.tableView.reset() def redo(self): self.undo_stack.redo() self.set_undo_redo_text() self.view.tableView.reset() def copy(self): if len(self.view.tableView.selectionModel().selectedIndexes()) == 0: return clipboard = QApplication.clipboard() selected_index = self.view.tableView.selectionModel().selectedIndexes()[0] selected_text = str(self.table_model.data(selected_index)) clipboard.setText(selected_text) def paste(self): if len(self.view.tableView.selectionModel().selectedIndexes()) == 0: return clipboard = QApplication.clipboard() index = self.view.tableView.selectionModel().selectedIndexes()[0] command = EditCommand(self.table_model, index) command.newValue(str(clipboard.text())) self.undo_stack.beginMacro("Paste") self.undo_stack.push(command) self.undo_stack.endMacro() self.set_undo_redo_text() self.view.tableView.reset() def insert_rows(self): if len(self.table_model.get_header()) == 0: self.statusBar().showMessage("Adding rows to an empty table without a header is not possible.") return start, amount = self.get_selection() self.undo_stack.beginMacro("Add Row") self.undo_stack.push(InsertRowsCommand(self.table_model, start, 1)) self.undo_stack.endMacro() self.set_undo_redo_text() def duplicate_rows(self): if len(self.view.tableView.selectionModel().selectedIndexes()) == 0: self.statusBar().showMessage("You must select the first column of the row you want to duplicate") return start, amount = self.get_selection() self.undo_stack.beginMacro("Duplicate Row") self.undo_stack.push(DuplicateRowCommand(self.table_model, start)) self.undo_stack.endMacro() self.set_undo_redo_text() self.view.tableView.reset() def remove_rows(self): if len(self.table_model.get_list()) == 0: self.statusBar().showMessage("WARNING: Removing rows from an empty table is not possible") return start, amount = self.get_selection() if start != len(self.table_model.get_list()): self.undo_stack.beginMacro("Remove Row(s)") self.undo_stack.push(RemoveRowsCommand(self.table_model, start, amount)) self.undo_stack.endMacro() self.set_undo_redo_text() else: self.statusBar().showMessage( "WARNING: You need to choose the rows you want to remove by selecting the cells in the " "first column" ) def new(self): if self.filename is not None: save = self.show_new_file_dialog() if save: self.save() self.filename = None self.table_model.set_list([], []) else: self.filename = None self.table_model.set_list([], []) else: self.filename = None self.table_model.set_list([], []) def show_append_override_dialog(self): msgBox = QtGui.QMessageBox() msgBox.setWindowTitle("Append or Override") msgBox.setText("Append or override the current entries?") msgBox.addButton("Append", QtGui.QMessageBox.YesRole) msgBox.addButton("Override", QtGui.QMessageBox.NoRole) return msgBox.exec_() def show_new_file_dialog(self): msgBox = QtGui.QMessageBox() msgBox.setWindowTitle("New file") msgBox.setText("Do you want to save first?") msgBox.addButton("Yes", QtGui.QMessageBox.YesRole) msgBox.addButton("No", QtGui.QMessageBox.NoRole) return msgBox.exec_() def open(self): try: fileName = QFileDialog.getOpenFileName( self, self.tr("Open CSV File"), os.getcwd(), self.tr("CSV Files (*.csv)") )[0] if fileName is not None and fileName is not "": append_or_override = False if self.filename is not None: append_or_override = self.show_append_override_dialog() self.filename = fileName self.table_model.open(self.filename, clear=append_or_override) self.undo_stack.clear() self.set_undo_redo_text() self.update_table_model(self.table_model.get_list(), self.table_model.get_header()) except FileNotFoundError: QtGui.QMessageBox.critical( self, "Read Error", 'Error reading CSV File:\nFile "' + self.filename + '" not found!', QtGui.QMessageBox.Close, ) except csv.Error: QtGui.QMessageBox.critical( self, "Read Error", "Error reading CSV File:\n File is not an valid CSV File!", QtGui.QMessageBox.Close ) except: QtGui.QMessageBox.critical( self, "Read Error", "Error reading CSV File:\nAn unknown Error occured!", QtGui.QMessageBox.Close ) raise def save(self): if self.filename is not None and self.filename is not "": self.table_model.save(self.filename) else: fileName = QFileDialog.getSaveFileName( self, caption="Save CSV File", dir=os.getcwd(), filter="CSV Files (*.csv)" )[0] if fileName is not None and fileName is not "": self.table_model.save(fileName) def save_as(self): fileName = QFileDialog.getSaveFileName( self, caption="Save CSV File", dir=os.getcwd(), filter="CSV Files (*.csv)" )[0] if fileName is not None and fileName is not "": self.table_model.save(fileName)
pixmap, icon = resources_cache[filename] b = QToolButton() b.setIcon(icon) b.setIconSize(pixmap.rect().size()) b.setMaximumWidth(pixmap.rect().width()) # 6 if name: b.setObjectName(name) return b from PySide.QtGui import QStyledItemDelegate from PySide.QtGui import QUndoCommand, QUndoStack, QLineEdit undo_stack = QUndoStack() class UndoProxyEdit(QUndoCommand): def __init__(self, old_value, new_value, proxy_model, index): super(UndoProxyEdit, self).__init__() self._old_value, self._new_value, self._proxy_model, self._index = old_value, new_value, proxy_model, index self.setText("Undo") def undo(self): mainlog.info("Undo") self._proxy_model.setData(self._index, self._old_value) def redo(self): mainlog.info("Redo")
class Controller(QtGui.QMainWindow): def __init__(self, parent=None): super().__init__(parent) self.undoStack = QUndoStack() self.view = Ui_MainWindow() self.view.setupUi(self) self.view.tableView.setSortingEnabled(True) self.view.tableView.setItemDelegate(ItemDelegate(self.undoStack, self.set_undo_redo_text)) self.filename = None self.table_model = CSVTableModel(datalist=[], header=[], parent=self) self.connect_elements() try: self.db = DBAccess(DBConfig.database, DBConfig.username, DBConfig.password, DBConfig.wahltermin) except Exception as e: print(e) Message.error("Database Error", "Error while trying to establish a database connection.") def show_window(self): self.show() self.raise_() def connect_elements(self): self.view.actionNew.triggered.connect(self.new) self.view.actionOpen.triggered.connect(self.open) self.view.actionSave.triggered.connect(self.save) self.view.actionSave_As.triggered.connect(self.save_as) self.view.actionAdd_Row.triggered.connect(self.add_rows) self.view.actionRemove_Row_s.triggered.connect(self.remove_rows) self.view.actionWrite.triggered.connect(self.write) self.view.actionLoad.triggered.connect(self.load) self.view.actionUndo.triggered.connect(self.undo) self.view.actionRedo.triggered.connect(self.redo) self.view.actionCopy.triggered.connect(self.copy) self.view.actionPaste.triggered.connect(self.paste) self.view.actionDuplicate_Row.triggered.connect(self.duplicate) self.view.actionCut.triggered.connect(self.cut) self.view.actionShow_Results.triggered.connect(self.show_results) def set_undo_redo_text(self): undo = "Undo" redo = "Redo" undo_text = self.undoStack.undoText() redo_text = self.undoStack.redoText() if undo_text: undo += " \"" + undo_text + "\"" if redo_text: redo += " \"" + redo_text + "\"" self.view.actionUndo.setText(undo) self.view.actionRedo.setText(redo) def show_results(self): # try: datalist, header = self.db.create_results() ResultsController(datalist, header, "Hochrechnungsergebnis") """ except Exception as e: print(e) Message.error("Database Error", "Error while accessing the database. Perhaps the schema in the database " "does not match the ddl-script.") """ def duplicate(self): if len(self.view.tableView.selectionModel().selectedIndexes()) == 0: Message.error("Error", "You must select the first column of the row you want to duplicate") return start, amount = self.get_selection() self.undoStack.beginMacro("Duplicate Row") self.undoStack.push(DuplicateRowCommand(self.table_model, start)) self.undoStack.endMacro() self.set_undo_redo_text() self.view.tableView.reset() def cut(self): self.copy() index = self.view.tableView.selectionModel().selectedIndexes()[0] command = EditCommand(self.table_model, index) command.newValue("") self.undoStack.beginMacro("Cut") self.undoStack.push(command) self.undoStack.endMacro() self.set_undo_redo_text() self.view.tableView.reset() def copy(self): if len(self.view.tableView.selectionModel().selectedIndexes()) == 0: return clipboard = QApplication.clipboard() selected_index = self.view.tableView.selectionModel().selectedIndexes()[0] selected_text = str(self.table_model.data(selected_index)) clipboard.setText(selected_text) def paste(self): if len(self.view.tableView.selectionModel().selectedIndexes()) == 0: return clipboard = QApplication.clipboard() index = self.view.tableView.selectionModel().selectedIndexes()[0] command = EditCommand(self.table_model, index) command.newValue(str(clipboard.text())) self.undoStack.beginMacro("Paste") self.undoStack.push(command) self.undoStack.endMacro() self.set_undo_redo_text() self.view.tableView.reset() def undo(self): self.undoStack.undo() self.set_undo_redo_text() self.view.tableView.reset() def redo(self): self.undoStack.redo() self.set_undo_redo_text() self.view.tableView.reset() def update_table_model(self, data, header): self.table_model.set_list(data, header) self.view.tableView.reset() self.view.tableView.setModel(self.table_model) def write(self): if self.filename is None or len(self.table_model.get_list()) == 0: Message.error("Writing to database not possible", "The table needs to contain of the same column headers " "as the original 'wahl.csv'.") return try: current_list = self.table_model.get_list() self.db.write_from_csv_list(current_list) except Exception as e: print(e) Message.error("Database Error", "Error while accessing the database. Perhaps the schema in the database " "does not match the ddl-script or the required table headers (see " "original 'wahl.csv') are not existing.") def load(self): try: datalist, header = self.db.load_into_csv_list() self.update_table_model(datalist, header) except Exception as e: print(e) Message.error("Database Error", "Error while accessing the database. Perhaps the schema in the database " "does not match the ddl-script.") def add_rows(self): if len(self.table_model.get_header()) == 0: Message.error("Error", "Adding rows to an empty table without a header is not possible.") return start, amount = self.get_selection() self.undoStack.beginMacro("Add Row") self.undoStack.push(InsertRowsCommand(self.table_model, start, 1)) self.undoStack.endMacro() self.set_undo_redo_text() def remove_rows(self): if len(self.table_model.get_list()) == 0: Message.error("Error", "Removing rows from an empty table is not possible.") return start, amount = self.get_selection() if start != len(self.table_model.get_list()): self.undoStack.beginMacro("Remove Row(s)") self.undoStack.push(RemoveRowsCommand(self.table_model, start, amount)) self.undoStack.endMacro() self.set_undo_redo_text() else: Message.error("Error", "You need to choose the rows you want to remove by selecting the cells in the " "first column") def get_zero_column_selected_indexes(self): selected_indexes = self.view.tableView.selectedIndexes() if not selected_indexes: return return [index for index in selected_indexes if not index.column()] def get_selection(self): zero_column_selected_indexes = self.get_zero_column_selected_indexes() if not zero_column_selected_indexes: return self.table_model.rowCount(self), 1 first_zero_column_selected_index = zero_column_selected_indexes[0] zero_column_selected_indexes = self.get_zero_column_selected_indexes() if not first_zero_column_selected_index or not first_zero_column_selected_index.isValid(): return False startingrow = first_zero_column_selected_index.row() return startingrow, len(zero_column_selected_indexes) def new(self): self.filename = None self.table_model.set_list([], []) def open(self): filename = QFileDialog.getOpenFileName(self, caption="Open CSV-File", filter="CSV-File (*.csv)")[0] if len(filename) > 0: self.filename = filename datalist, header = CSV.read(self.filename) self.update_table_model(datalist, header) def save(self): if self.filename is not None: CSV.write(self.filename, self.table_model.get_list()) else: self.save_as() def save_as(self): filename = QFileDialog.getSaveFileName(self, caption="Save CSV-File", dir=self.filename, filter="CSV-File (*.csv)")[0] if len(filename) > 0: self.filename = filename self.save()
class Model(QObject): """ MVC - Pattern: Represents the entities class """ tableModelChangedSignal = Signal(QAbstractTableModel, QModelIndex, str, str) def __init__(self): super(Model, self).__init__() self.current_file = None self.session = None # Setting up SQL relevant stuff self.wahl_nummer = 1 self.undostack = QUndoStack() def find_indeces(self, header): """ find the indeces for some items in the given header and returns them as a dictionary :param header: Array Header of the table model :return: """ indeces = {'T': None, 'WV': None, 'WK': None, 'BZ': None, 'SPR': None, 'WBER': None, 'ABG.': None, 'UNG.': None, 'SPOE': None, 'FPOE': None, 'OEVP': None, 'GRUE': None, 'NEOS': None, 'WWW': None, 'ANDAS': None, 'GFW': None, 'SLP': None, 'WIFF': None, 'M': None, 'FREIE': None} for index, item in enumerate(header): indeces[item] = index return indeces def create_session(self, username, password, hostname, database, port=3306): """ Creates a session to the given creadentials :param username: str :param password: str :param hostname: str :param database: str :param port: int Default is 3306 """ engine = create_engine("mysql+mysqlconnector://%s:%s@%s:%s/%s" % (username, password, hostname, port, database)) if self.session is not None: self.session.close() Session = sessionmaker(bind=engine, autoflush=False) self.session = Session() def insert_into_db(self, table_model): tmp = [] if table_model is not None: arr = table_model.get_data_as_2d_array() # Remove spaces for x in range(0, len(arr)): for y in range(0, len(arr[x])): arr[x][y] = arr[x][y].replace(" ", "") indeces = self.find_indeces(arr[0]) partei_index = indeces['UNG.']+1 parteien = self.session.query(Partei).all() progress = 1 tmp = [] for data in arr[1:]: print("%f" % (progress/(len(arr)-1)*100) + " %") # Sprengel sprengel = Sprengel() sprengel.nummer = data[indeces['SPR']] sprengel.wahlberechtigte = data[indeces['WBER']] sprengel.ungueltige = data[indeces['UNG.']] sprengel.abgegebene = data[indeces['ABG.']] sprengel.bznr = data[indeces['BZ']] sprengel.whnr = self.wahl_nummer for actual_partei_index in range(partei_index, len(arr[0])-1): if data[indeces['T']] == '4' and data[indeces['WV']] == '1': # Stimmen stimmen = Stimmen() stimmen.anzahl = data[actual_partei_index] for partei in parteien: if partei.bezeichnung == arr[0][actual_partei_index]: stimmen.parteinr = partei.nummer stimmen.spnr = sprengel.nummer stimmen.bznr = data[indeces['BZ']] stimmen.whnr = self.wahl_nummer self.session.add(stimmen) else: raise Exception("Wrong CSV Format, expected Column T to be 4 and Column WV to be 1") self.session.add(sprengel) progress += 1 try: print("Sending to database...") self.session.commit() except Exception as e: print("Could'nt insert into database, there are duplicate entries.") def undo(self): self.undostack.undo() def redo(self): self.undostack.redo() def copy(self, table_model, index): """ Copies the data from the given TableModel at the current index to the clipboard :param table_model: QAbstractTableModel :param index: QModelIndex """ pyperclip.copy(table_model.data(index, Qt.DisplayRole)) def paste(self, table_model, index): """ Pastes the data from the clipboard to the TableModel at the given index :param table_model: QAbstractTableModel :param index: QModelIndex """ old_value = table_model.data(index, Qt.DisplayRole) new_value = pyperclip.paste() self.undostack.push(EditCommand(table_model, index, old_value, new_value)) del old_value, new_value def cut(self, table_model, index): """ Cuts the data from the given TableModel at the current index to the clipboard :param table_model: QAbstractTableModel :param index: QModelIndex """ old_value = table_model.data(index, Qt.DisplayRole) new_value = "" self.copy(table_model, index) self.undostack.push(EditCommand(table_model, index, old_value, new_value)) del old_value, new_value def show_from_database(self, table_model): """ Loads the data from the database into the TableModel """ arr = [4, 1] # TODO def duplicate_row(self, table_model, row): """ Duplicates row at the current row :param row: Row number """ # TODO undostack self.undostack.push(DuplicateRowCommand(table_model, row, table_model.get_rows(row))) # table_model.duplicateRow(row) def delete_rows(self, table_model, row, count): """ Deletes the current focused row :param count: :param row: :param table_model: """ self.undostack.push(DeleteRowCommand(table_model, row, table_model.get_rows(row, count=count))) def insert_row(self, table_model, row, count): """ Inserts a blank row at the current row index :param table_model: QAbstractTableModel :param row: int :param count: int """ self.undostack.push(InsertRowCommand(table_model, row, count)) @Slot(QAbstractTableModel, QModelIndex, str, str) def table_model_changed(self, table_model, index, old, new): """ Will be executed when data in the table model has been changed :param table_model: QAbstractTableModel TableModel where data has been changed :param index: QModelIndex :param old: QVariant Old TableModel data :param new: QVariant New TableModel data """ self.undostack.push(EditCommand(table_model, index, old, new)) # print("TableModel changed at [%s, %s]" % (index.row(), index.column())) # print("Old Value: %s | New Value: %s" % (old, new)) def exit_handler(self): if self.session is not None: self.session.close()