Ejemplo n.º 1
0
class MyWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        # Собираем окно
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.retranslateUi(self)
        self.db_path = r'database/database.sqlite3'
        self.ui.path_db.setText(self.db_path)

        # Собираем кнопки
        self.save_db = QAction(QIcon('icon/save.png'), 'Save', self)
        self.open_db_file = QAction(QIcon('icon/open-db.png'), 'Open', self)
        self.add_row = QAction(QIcon('icon/add.png'), 'Add row', self)
        self.del_row = QAction(QIcon('icon/del.png'), ' Del row', self)
        self.ui.toolBar.addAction(self.save_db)
        self.ui.toolBar.addAction(self.open_db_file)
        self.ui.toolBar.addAction(self.add_row)
        self.ui.toolBar.addAction(self.del_row)
        self.db = None
        self.table_model = None
        # Подключаемся к БД
        self.open_db()
        # действуем по триггерам
        self.add_row.triggered.connect(self.add_row_action)
        self.del_row.triggered.connect(self.del_row_action)
        self.save_db.triggered.connect(self.save_change_db)
        self.open_db_file.triggered.connect(self.open_db_file_action)
        self.ui.comboBox.currentIndexChanged.connect(self.show_table)

    def open_db(self):
        # Подключение к БД
        self.db = QSqlDatabase.addDatabase('QSQLITE')
        self.db.setDatabaseName(self.db_path)
        self.db.open()
        self.get_tables_name()
        self.show_table()

    def get_tables_name(self):
        self.ui.comboBox.clear()
        for table_name in self.db.tables():
            self.ui.comboBox.addItem(table_name)

    def show_table(self):
        self.table_model = QSqlRelationalTableModel()
        table = self.ui.comboBox.currentText()
        if table == 'goods':
            self.create_goods_table_model()
        elif table == 'employees':
            self.create_employees_table_model()
        else:
            self.table_model.setTable(table)
            self.table_model.select()
        self.table_model.setEditStrategy(QSqlTableModel.OnManualSubmit)
        view = self.ui.tableView
        view.setModel(self.table_model)
        view.setItemDelegate(QSqlRelationalDelegate(view))

    def create_goods_table_model(self):
        self.table_model.setTable('goods')
        self.table_model.setRelation(2, QSqlRelation('units', 'unit_id', 'unit'))
        self.table_model.setRelation(3, QSqlRelation('categories', 'category_id', 'category_name'))
        self.table_model.select()

    def create_employees_table_model(self):
        self.table_model.setTable('employees')
        self.table_model.setRelation(2, QSqlRelation('positions', 'position_id', 'position'))
        self.table_model.select()

    def add_row_action(self):
        self.table_model.insertRows(self.table_model.rowCount(), 1)

    def del_row_action(self):
        rs = list(map(lambda x: x.row(), self.ui.tableView.selectedIndexes()))
        print(rs)
        for i in rs:
            self.table_model.removeRows(i, 1)

    def open_db_file_action(self):
        self.db_path = QFileDialog.getOpenFileName(self, "Open file")[0]
        self.ui.path_db.setText(self.db_path)
        self.db.close()
        self.open_db()

    def save_change_db(self):
        if self.table_model.submitAll():
            self.ui.statusbar.showMessage('Изменения сохранены')
        else:
            self.ui.statusbar.showMessage(f'{self.table_model.lastError().text()}')
Ejemplo n.º 2
0
class Setup():
    def __init__(self):
        self.loading_screen()
        self.data = None
        self.output_data = None
        self.colors = [
            '#f0e443', '#f77e45', '#f74940', '#4bfa91', '#69d1d1', '#4a61f7'
        ]
        self.version = '1.0.1'
        self.map = [{
            'Excellent': 5,
            'Very Good': 4,
            'Good': 3,
            'Poor': 2,
            'Very Poor': 1
        }, {
            'Yes': 3,
            'Partially Completed': 2,
            'No': 1
        }]

        self.root = QMainWindow()
        self.window = Ui_MainWindow()
        self.window.setupUi(self.root)
        self.window.retranslateUi(self.root)

        self.window.menuFile.addAction(QIcon('icons/open.ico'), 'Open',
                                       self.open_func, 'Ctrl+O')
        self.window.menuFile.addSeparator()
        self.window.menuFile.addAction(QIcon('icons/save.ico'), 'Save',
                                       self.create_output, 'Ctrl+S')
        self.window.menuFile.addSeparator()
        self.window.menuFile.addAction(QIcon('icons/exit.ico'), 'Quit',
                                       lambda: exit(), 'Ctrl+Q')

        self.window.menuOptions.addAction(QIcon('icons/setting.ico'),
                                          'Setting', self.open_setting,
                                          'Ctrl+X')
        self.window.menuOptions.addAction(QIcon('icons/color'), 'Colors',
                                          self.change_graph_color, 'Ctrl+J')

        self.window.menuHelp.addAction(QIcon('icons/about.ico'), 'About',
                                       self.about_func, 'Ctrl+H')
        self.window.menuHelp.addAction(QIcon('icons/update.ico'),
                                       'Check for update', self.check_update,
                                       'Ctrl+U')

        self.window.open_button.clicked.connect(self.open_func)
        self.window.drop_button.clicked.connect(self.drop_func)
        self.window.select_button.clicked.connect(self.select_func)
        self.window.copy_csv_button.clicked.connect(self.copy_func)
        self.window.save_button.clicked.connect(self.create_output)

        self.window.column_list.setStyleSheet('color: blue;')

        self.root.show()

    def loading_screen(self):
        self.top = QSplashScreen(QPixmap('icons/logo.png'))
        self.top.show()
        QTimer.singleShot(1000, self.top.close)

    def open_func(self):
        self.file_dialog = QFileDialog()
        file_path, _ = self.file_dialog.getOpenFileName()
        if file_path != '':
            try:
                self.data = pd.read_csv(file_path)
                self.update_table()
            except Exception as e:
                self.top = Ui_Error()
                self.top_widget = QWidget()
                self.top.setupUi(self.top_widget)
                self.top.retranslateUi(self.top_widget)
                self.top.textBrowser.setTextColor(QColor(255, 0, 0))
                self.top.textBrowser.setText(repr(e))
                self.top_widget.show()

    def update_table(self):
        if self.data.__class__.__name__ == 'DataFrame':
            self.df_model = PandasModel(self.data)
            self.window.data_table.setModel(self.df_model)
            self.window.data_table.setStyleSheet('''QHeaderView::section{
                        background-color: '#dcf7f7';
                        color: blue;
                        border: 0;}''')
            self.window.column_list.clear()
            self.window.column_list.addItems(list(self.data))

            c = 0
            for i in range(self.window.column_list.count()):
                self.window.column_list.item(i).setSizeHint(QSize(100, 35))
                if c:
                    self.window.column_list.item(i).setBackground(
                        QColor('#dcf7f7'))
                    c = 0
                else:
                    self.window.column_list.item(i).setBackground(
                        QColor('#ffffff'))
                    c = 1

    def drop_func(self):
        if self.data.__class__.__name__ == 'DataFrame':
            col = [
                tmp.text() for tmp in self.window.column_list.selectedItems()
            ]
            self.data.drop(col, axis=1, inplace=True)
            self.update_table()

    def select_func(self):
        if self.data.__class__.__name__ == 'DataFrame':
            col = [
                tmp.text() for tmp in self.window.column_list.selectedItems()
            ]
            self.data = self.data[col].copy()
            self.update_table()

    def copy_func(self):
        if self.data.__class__.__name__ == 'DataFrame':
            tmp = '\\skfgi_feed_back_copy_' + str(
                datetime.isoformat(datetime.now())) + '.csv'
            tmp = tmp.replace(':', '-')
            tmp = os.path.expanduser('~') + tmp
            self.data.to_csv(tmp, index=False)
            self.msg_box = QMessageBox()
            self.msg_box.setWindowIcon(QIcon('icons/logo.png'))
            self.msg_box.setWindowTitle('Data Saved')
            self.msg_box.setInformativeText('New csv file is saved as :\n' +
                                            tmp)
            self.msg_box.show()

    def about_func(self):
        self.top = Ui_About()
        self.top_widget = QWidget()
        self.top.setupUi(self.top_widget)
        self.top.retranslateUi(self.top_widget)

        tmp = os.path.join(os.path.dirname(__file__),
                           'Documentation/index.html').replace('/', '\\')
        self.top.doc_button.clicked.connect(lambda: webbrowser.open(tmp))

        self.top_widget.show()

    def check_update(self):
        try:
            self.top = QSplashScreen(QPixmap('icons/wait.png'))
            self.top.show()
            QTimer.singleShot(3000, self.top.close)

            resp = requests.get(
                url=
                'https://raw.githubusercontent.com/SubhoBasak/SKFGI_feedback_analyzer/master/Output/version.txt'
            )
            resp = resp.text.strip('\n').strip()
            self.tmp = QMessageBox()
            self.tmp.setWindowTitle('Update')
            self.tmp.setWindowIcon(QIcon('icons/logo.png'))
            if resp != self.version:
                self.tmp.setInformativeText(
                    'New update available!\nDownlaod from : https://github.com/SubhoBasak/SKFGI_feedback_analyzer/tree/master/Output'
                )
            else:
                self.tmp.setInformativeText('Already up-to-date')
            self.tmp.show()
        except Exception as e:
            self.top = Ui_Error()
            self.top_widget = QWidget()
            self.top.setupUi(self.top_widget)
            self.top.retranslateUi(self.top_widget)
            self.top.textBrowser.setTextColor(QColor(255, 0, 0))
            self.top.textBrowser.setText(repr(e))
            self.top_widget.show()

    def open_setting(self):
        self.top = Ui_Setting()
        self.top_widget = QWidget()
        self.top.setupUi(self.top_widget)
        self.top.retranslateUi(self.top_widget)

        tmp = [(self.top.map_in_1, self.top.map_out_1),
               (self.top.map_in_2, self.top.map_out_2),
               (self.top.map_in_3, self.top.map_out_3),
               (self.top.map_in_4, self.top.map_out_4),
               (self.top.map_in_5, self.top.map_out_5)]

        for x, y in zip(tmp, self.map[0].items()):
            x1, x2 = x
            y1, y2 = y
            x1.setText(y1), x2.setText(str(y2))

        tmp = [(self.top.map_in_11, self.top.map_out_11),
               (self.top.map_in_12, self.top.map_out_12),
               (self.top.map_in_13, self.top.map_out_13)]

        for x, y in zip(tmp, self.map[1].items()):
            x1, x2 = x
            y1, y2 = y
            x1.setText(y1), x2.setText(str(y2))

        self.top.map_ok_button.clicked.connect(self.change_map)
        self.top_widget.show()

    def change_map(self):
        tmp = [(self.top.map_in_1, self.top.map_out_1),
               (self.top.map_in_2, self.top.map_out_2),
               (self.top.map_in_3, self.top.map_out_3),
               (self.top.map_in_4, self.top.map_out_4),
               (self.top.map_in_5, self.top.map_out_5)]

        self.map = [{}, {}]
        for x, y in tmp:
            self.map[0][x.text()] = y.text()

        tmp = [(self.top.map_in_11, self.top.map_out_11),
               (self.top.map_in_12, self.top.map_out_12),
               (self.top.map_in_13, self.top.map_out_13)]

        for x, y in tmp:
            self.map[1][x.text()] = y.text()
        self.top_widget.close()

    def change_graph_color(self):
        self.top = Ui_ColorPicker()
        self.top_widget = QWidget()
        self.top.setupUi(self.top_widget)
        self.top.retranslateUi(self.top_widget)

        buttons = [
            self.top.color1_button, self.top.color2_button,
            self.top.color3_button, self.top.color4_button,
            self.top.color5_button, self.top.color6_button
        ]

        funcs = [
            self.get_color1, self.get_color2, self.get_color3, self.get_color4,
            self.get_color5, self.get_color6
        ]

        for i, b in enumerate(buttons):
            b.setStyleSheet('background : ' + self.colors[i] + ';')
            b.clicked.connect(funcs[i])

        self.top.close_color_picker.clicked.connect(self.top_widget.close)
        self.top_widget.show()

    def get_color1(self):
        win = QColorDialog()
        win.setWindowIcon(QIcon('icons/logo.png'))
        self.colors[0] = win.getColor().name()
        self.top.color1_button.setStyleSheet('background : ' + self.colors[0])

    def get_color2(self):
        win = QColorDialog()
        win.setWindowIcon(QIcon('icons/logo.png'))
        self.colors[1] = win.getColor().name()
        self.top.color2_button.setStyleSheet('background : ' + self.colors[1])

    def get_color3(self):
        win = QColorDialog()
        win.setWindowIcon(QIcon('icons/logo.png'))
        self.colors[2] = win.getColor().name()
        self.top.color3_button.setStyleSheet('background : ' + self.colors[2])

    def get_color4(self):
        win = QColorDialog()
        win.setWindowIcon(QIcon('icons/logo.png'))
        self.colors[3] = win.getColor().name()
        self.top.color4_button.setStyleSheet('background : ' + self.colors[3])

    def get_color5(self):
        win = QColorDialog()
        win.setWindowIcon(QIcon('icons/logo.png'))
        self.colors[4] = win.getColor().name()
        self.top.color5_button.setStyleSheet('background : ' + self.colors[4])

    def get_color6(self):
        win = QColorDialog()
        win.setWindowIcon(QIcon('icons/logo.png'))
        self.colors[5] = win.getColor().name()
        self.top.color6_button.setStyleSheet('background : ' + self.colors[5])

    def create_output(self):
        self.top = QSplashScreen(QPixmap('icons/wait.png'))
        self.top.show()

        self.thread = threading.Thread(target=self.thread_func)
        self.thread.start()

        QTimer.singleShot(10000, self.top.close)

    def thread_func(self):
        self.prepare_output_data()
        self.calculate_percentage_and_plot()
        tmp_path = self.create_pdf()
        webbrowser.open(tmp_path)

    def create_pdf(self):
        pdf_file = FPDF()
        pdf_file.add_page()
        for i in os.listdir('Tmp'):
            i = 'Tmp/' + i
            pdf_file.image(os.path.join(os.path.dirname(__file__), i),
                           w=196,
                           h=116)
            pdf_file.ln()
        tmp_path = os.path.join(
            os.path.expanduser('~'), 'feed_back' +
            datetime.now().isoformat().replace(':', '-') + '.pdf')
        pdf_file.output(tmp_path, 'F')
        return tmp_path

    def calculate_percentage_and_plot(self):
        if self.output_data.__class__.__name__ == 'DataFrame':
            for file in os.listdir('Tmp'):
                os.remove('Tmp/' + file)
            fig = plt.figure(figsize=(12, 7))
            main_group = self.output_data.groupby('subject')

            for name, grp in main_group:
                teachers_name = grp['teacher'].unique()
                q = []
                p = []
                count = 1
                for qus_, qus_grp in grp.groupby('question'):
                    p.append(round(qus_grp.mean()['feedback'], 1))
                    q.append('Q' + str(count))
                    count += 1

                fig.clf()
                axs1 = fig.add_axes([0.07, 0.1, 0.7, 0.8])
                fig.suptitle(name + '-' + '-'.join(teachers_name),
                             fontsize=25,
                             color='orange')
                axs1.bar(q, p, color=self.colors)
                axs1.set_xticklabels(q, fontsize=22)
                axs1.set_yticklabels([20, 40, 60, 80, 100], fontsize=22)
                for xx, yy in enumerate(p):
                    axs1.text(xx - 0.4, yy, yy, fontsize=13)

                axs2 = fig.add_axes([0.8, 0.1, 0.1, 0.8])
                table_data = np.c_[q, p]
                length = len(table_data)
                cell_colors = [('#ffffff', '#ffffff'),
                               ('#e6f0f0', '#e6f0f0')] * (length // 2)
                if length % 2 != 0:
                    cell_colors += [('#ffffff', '#ffffff')]
                tab = axs2.table(table_data,
                                 loc='upper center',
                                 cellColours=cell_colors,
                                 cellLoc='center')
                tab.set_fontsize(25)
                tab.scale(1, 2)
                axs2.axis(False)
                fig.savefig('Tmp/' + name + '-' + '-'.join(teachers_name) +
                            '.png')

    def prepare_output_data(self):
        if self.data.__class__.__name__ == 'DataFrame':
            try:
                self.output_data = {
                    'question': [],
                    'subject': [],
                    'teacher': [],
                    'feedback': []
                }
                ln = len(self.data)
                for col in self.data:
                    qus, sub, tec = col.split('[')
                    self.output_data['question'].append(qus.strip().strip(']'))
                    self.output_data['subject'].append(sub.strip().strip(']'))
                    self.output_data['teacher'].append(tec.strip().strip(']'))

                    sup_flag = 0
                    for m in self.map:
                        flag = 1
                        tmp_unique = m.keys()
                        for k in self.data[col].unique():
                            if k not in tmp_unique:
                                flag = 0
                                break
                        if flag:
                            tmp_col = self.data[col].map(m).astype('int32')
                            tmp_max = max(m.values())
                            sup_flag = 1
                            break
                    if not sup_flag:
                        self.top = Ui_Error()
                        self.top_widget = QWidget()
                        self.top.setupUi(self.top_widget)
                        self.top.retranslateUi(self.top_widget)

                        self.top.textBrowser.setText(
                            'Mapping error! Please set the map values proerly.\nOptions >> Settings'
                        )
                        self.top.textBrowser.setTextColor(QColor(255, 0, 0))

                        self.top_widget.show()
                    else:
                        self.output_data['feedback'].append(
                            round(
                                100 * tmp_col.values.sum() /
                                (tmp_max * len(tmp_col)), 2))
                self.output_data = pd.DataFrame(self.output_data)
            except Exception as e:
                self.top = Ui_Error()
                self.top_widget = QWidget()
                self.top.setupUi(self.top_widget)
                self.top.retranslateUi(self.top_widget)
                self.top.textBrowser.setTextColor(QColor(255, 0, 0))
                self.top.textBrowser.setText(repr(e))
                self.top_widget.show()
Ejemplo n.º 3
0
class MyWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.retranslateUi(self)
        self.db_path = r'database\sklad_db.sqlite3'
        self.ui.path_db.setText(self.db_path)

        self.save_db = QAction(QIcon('icon/save.png'), 'Сохранить', self)
        self.find_db_file = QAction(QIcon('icon/open_db.png'), 'Открыть БД',
                                    self)
        self.add_rec = QAction(QIcon('icon/add.png'), 'Добавить запись', self)
        self.del_rec = QAction(QIcon('icon/del.png'), 'Удалить запись', self)
        self.ui.toolBar.addAction(self.save_db)
        self.ui.toolBar.addAction(self.find_db_file)
        self.ui.toolBar.addAction(self.add_rec)
        self.ui.toolBar.addAction(self.del_rec)
        self.db = None
        self.table_model = None

        self.open_db()

        self.add_rec.triggered.connect(self.add_record_action)
        self.del_rec.triggered.connect(self.del_record_action)
        self.save_db.triggered.connect(self.save_change_db)
        self.find_db_file.triggered.connect(self.find_db_file_action)
        self.ui.comboBox.currentIndexChanged.connect(self.show_table)

    def open_db(self):
        self.db = QSqlDatabase.addDatabase('QSQLITE')
        self.db.setDatabaseName(self.db_path)
        self.db.open()
        self.get_table_name()
        self.show_table()

    def get_table_name(self):
        self.ui.comboBox.clear()
        table_name_ru = None
        for table_name in self.db.tables():
            if table_name == 'goods':
                table_name_ru = 'Товары'
            elif table_name == 'categories':
                table_name_ru = 'Категории'
            elif table_name == 'units':
                table_name_ru = 'Единица измерения'
            elif table_name == 'employees':
                table_name_ru = 'Персонал'
            elif table_name == 'positions':
                table_name_ru = 'Должности'
            elif table_name == 'vendors':
                table_name_ru = 'Поставщики'
            self.ui.comboBox.addItem(table_name_ru)

    def show_table(self):
        self.table_model = QSqlRelationalTableModel()
        table = self.ui.comboBox.currentText()
        if table == 'Товары':
            self.create_goods_table_model()
        elif table == 'Персонал':
            self.create_employees_table_model()
        else:
            if table == 'Единица измерения':
                table = 'units'
            elif table == 'Категории':
                table = 'categories'
            elif table == 'Должности':
                table = 'positions'
            elif table == 'Поставщики':
                table = 'vendors'
            self.table_model.setTable(table)
            self.table_model.select()
        self.table_model.setEditStrategy(QSqlTableModel.OnManualSubmit)
        view = self.ui.tableView
        view.setModel(self.table_model)
        view.setItemDelegate(QSqlRelationalDelegate(view))

    def create_goods_table_model(self):
        self.table_model.setTable('goods')
        self.table_model.setRelation(2, QSqlRelation('units', 'unit_id',
                                                     'unit'))
        self.table_model.setRelation(
            3, QSqlRelation('categories', 'category_id', 'category_name'))
        self.table_model.select()

    def create_employees_table_model(self):
        self.table_model.setTable('employees')
        self.table_model.setRelation(
            2, QSqlRelation('positions', 'position_id', 'position'))
        self.table_model.select()

    def add_record_action(self):
        self.ui.statusbar.clearMessage()
        self.table_model.insertRows(self.table_model.rowCount(), 1)

    def del_record_action(self):
        self.ui.statusbar.clearMessage()
        rs = list(map(lambda x: x.row(), self.ui.tableView.selectedIndexes()))
        #print(rs)
        for i in rs:
            self.table_model.removeRows(i, 1)

    def find_db_file_action(self):
        self.db_path = QFileDialog.getOpenFileName(self, "Open file")[0]
        self.ui.path_db.setText(self.db_path)
        self.db.close()
        self.open_db()

    def save_change_db(self):
        if self.table_model.submitAll():
            self.ui.statusbar.showMessage('Изменения сохранены')
        else:
            self.ui.statusbar.showMessage(
                f'{self.table_model.lastError().text()}')