Пример #1
0
    def __init__(self, professor, session, flags=None, *args, **kwargs):
        super().__init__(flags, *args, **kwargs)

        main_layout = QVBoxLayout()
        group = QMComboBox(Group)
        discipline = QMComboBox(Discipline)

        main_layout.addWidget(QMSelector([discipline, group], professor),
                              alignment=Qt.AlignTop)

        def on_group_select(lessons: List[Lesson], group):
            self.first_lesson = sorted(lessons,
                                       key=lambda lesson: lesson.date)[0]
            self.revoke_step.emit(self.steps[2])
            self.file_name = None
            start_button.setEnabled(False)

        group.current_changed.connect(on_group_select)
        group.current_changed.connect(
            lambda x, y: self.step.emit(self.steps[0]))
        discipline.current_changed.connect(
            lambda x, y: self.step.emit(self.steps[1]))

        button = QPushButton('Выбрать файл')

        def on_button_click():
            file, status = QFileDialog().getOpenFileName(
                self, 'Выберите файл', '', 'Sheet (*.xls *.xlsx)')
            if status:
                self.file_name = file
                self.step.emit(self.steps[2])
                start_button.setEnabled(True)
                start_button.setText(f'Считать из файла {Path(file).name}')

        button.clicked.connect(on_button_click)

        def start():
            self.reader = VisitationExcelLoader(
                file_name=self.file_name,
                group=list(group.current()),
                discipline=discipline.current(),
                session=session)

        start_button = QPushButton('Считать из файла')
        start_button.setEnabled(False)
        start_button.clicked.connect(start)

        main_layout.addWidget(button,
                              alignment=Qt.AlignHCenter | Qt.AlignVCenter)
        main_layout.addWidget(start_button,
                              alignment=Qt.AlignHCenter | Qt.AlignTop)

        self.setLayout(main_layout)
Пример #2
0
    def __init__(self, lesson: Lesson, student: Student):
        super().__init__()
        self.lesson = lesson
        self.student = student
        self.remove_file_on_close: List[Path] = []

        self.setWindowModality(Qt.ApplicationModal)
        self.setMinimumSize(450, 250)

        self.r = VisitationLossReason.get(lesson.session(),
                                          lesson_id=lesson.id,
                                          student_id=student.id)

        self.grid = QGridLayout()

        self.setWindowTitle("Добавить причину пропуска")

        self.grid.addWidget(QLabel('Студент'), 0, 0, 1, 2)
        student_name_label = QLabel(student.short_name())
        student_name_label.setObjectName('InfoLabel')
        self.grid.addWidget(student_name_label, 0, 2, 1, 2)

        self.grid.addWidget(QLabel('Занятие'), 1, 0, 1, 2)
        lesson_name_label = QLabel(name(lesson))
        lesson_name_label.setObjectName('InfoLabel')
        self.grid.addWidget(lesson_name_label, 1, 2, 1, 2)

        self.reason = QMComboBox(LossReason)
        self.grid.addWidget(QLabel('Причина'), 2, 0, 1, 2)
        self.grid.addWidget(self.reason, 2, 2, 1, 2)

        self.file_attach = QAttachFile('rb', ('pdf', 'docx', 'img'))
        self.grid.addWidget(self.file_attach, 3, 0, 2, 4)

        self.grid.addWidget(QAccentCancelButtons(self._accept, self.close), 5,
                            0, 1, 4)

        self.setLayout(self.grid)

        if self.r is not None:
            self.reason.setCurrent(self.r.reason)
            if self.r.file is not None:
                file_path = writeTempFile(self.r.file, self.r.file_ext)
                self.file_attach.set_file(file_path)
                self.remove_file_on_close.append(file_path)
Пример #3
0
    def __init__(self, students: List[Student], parent=None):
        super().__init__(parent)

        self.setWindowModality(Qt.ApplicationModal)

        def fill_combo(with_card):
            self.combo.clear()
            self.combo.addItems(list(filter(lambda student: with_card or student.card_id is None, students)))

        self.label = QLabel("Для введенной карты не обнаружен студент.\n"
                            "Выберите студента для введеной карты из списка ниже.")

        self.combo = QMComboBox(Student)
        self.combo.formatter = lambda student: f'{Group.names(student.groups)} | {student.full_name()}'

        self.show_all_students = QCheckBox("Показать всех студентов")
        self.show_all_students.toggled.connect(fill_combo)

        self.ok_button = QPushButton("Подтвердить")
        self.ok_button.clicked.connect(lambda: self.select.emit(self.combo.current()))

        self.cancel_button = QPushButton("Отмена")
        self.cancel_button.clicked.connect(self.cancel)

        main_layout = QVBoxLayout()
        main_layout.addWidget(self.label)
        main_layout.addWidget(self.show_all_students)
        main_layout.addWidget(self.combo)

        button_layout = QHBoxLayout()
        button_layout.addWidget(self.ok_button)
        button_layout.addWidget(self.cancel_button)

        main_layout.addLayout(button_layout)

        self.setLayout(main_layout)

        fill_combo(self.show_all_students.isChecked())

        self.select.connect(self.close)
        self.cancel.connect(self.close)
Пример #4
0
class QAddLossReason(BisitorWidget):
    def __init__(self, lesson: Lesson, student: Student):
        super().__init__()
        self.lesson = lesson
        self.student = student
        self.remove_file_on_close: List[Path] = []

        self.setWindowModality(Qt.ApplicationModal)
        self.setMinimumSize(450, 250)

        self.r = VisitationLossReason.get(lesson.session(),
                                          lesson_id=lesson.id,
                                          student_id=student.id)

        self.grid = QGridLayout()

        self.setWindowTitle("Добавить причину пропуска")

        self.grid.addWidget(QLabel('Студент'), 0, 0, 1, 2)
        student_name_label = QLabel(student.short_name())
        student_name_label.setObjectName('InfoLabel')
        self.grid.addWidget(student_name_label, 0, 2, 1, 2)

        self.grid.addWidget(QLabel('Занятие'), 1, 0, 1, 2)
        lesson_name_label = QLabel(name(lesson))
        lesson_name_label.setObjectName('InfoLabel')
        self.grid.addWidget(lesson_name_label, 1, 2, 1, 2)

        self.reason = QMComboBox(LossReason)
        self.grid.addWidget(QLabel('Причина'), 2, 0, 1, 2)
        self.grid.addWidget(self.reason, 2, 2, 1, 2)

        self.file_attach = QAttachFile('rb', ('pdf', 'docx', 'img'))
        self.grid.addWidget(self.file_attach, 3, 0, 2, 4)

        self.grid.addWidget(QAccentCancelButtons(self._accept, self.close), 5,
                            0, 1, 4)

        self.setLayout(self.grid)

        if self.r is not None:
            self.reason.setCurrent(self.r.reason)
            if self.r.file is not None:
                file_path = writeTempFile(self.r.file, self.r.file_ext)
                self.file_attach.set_file(file_path)
                self.remove_file_on_close.append(file_path)

    def _accept(self):
        file = self.file_attach.get_file()
        if self.r is None:
            res = QMessageBox().question(
                self, "Подтвердите действие",
                f"Будет добавлена запись для {self.student.short_name()} о пропуске занятия "
                + f"из-за {inflect(self.reason.current().value, {'gent'})} " +
                (f"без подтверждения"
                 if file is None else f"с подтверждением"))

            if res == QMessageBox.Yes:
                self.r = VisitationLossReason(lesson_id=self.lesson.id,
                                              student_id=self.student.id,
                                              reason=self.reason.current())
                if file is not None:
                    self.r.set_file(self.file_attach.get_path())

                self.lesson.session().add(self.r)

                self.r.session().commit()

                QMessageBox().information(
                    self, "Успешно добавлено",
                    "Успешно добавлена информация о пропуске")
                self.close()
        else:
            msg = f"В записи для {self.student.short_name()} о пропуске занятия будет изменено"
            changed = False
            if self.reason.current() != self.r.reason:
                msg += f'\n Причина: с {self.r.reason} на {self.reason.current()}'
                changed = True
            if file != self.r.file:
                if self.r.file is None:
                    msg += f'\n Добавлен файл подтверждения'
                else:
                    msg += f'\n Выбран другой файл'
                changed = True

            if changed:
                res = QMessageBox().question(self, "Подтвердите изменения",
                                             msg)

                if res:
                    self.r.reason = self.reason.current()
                    self.r.set_file(self.file_attach.get_path())
                    self.r.session().commit()
                    QMessageBox().information(
                        self, "Успешно изменено",
                        "Успешно изменена информация о пропуске")
                    self.close()
            else:
                self.close()

    def close(self):
        for file_path in self.remove_file_on_close:
            file_path.unlink()

        super().close()
Пример #5
0
    def __init__(self, user: _DBObject, *args, **kwargs):
        from Client.MyQt.Widgets.ComboBox import QMCheckedComboBox, QMComboBox

        super().__init__(*args, **kwargs)
        data_groups: List[Type[_DBRoot or _DBObject]] = sorted(_DBRoot.__subclasses__(), key=lambda x: x.__type_name__)
        plot_types = {
            "Посещения по неделям": ('bar_week', "Показывает уровень посещений на каждой неделе"),
            'Распределение': ('distribution', "Показывает итоговый уровень посещений на дату"),
            "Посещения по дням недели": ("bar_weekday", "Показывает уровень посещений по дням недели"),
            "Посещения по занятиям": ("bar_lesson", "Показывает уровень посещения по времени начала начала занятия"),
            "Гистограма": ('hist', "Показывает частоту каждого уровня посещений"),
            "Итоговое (по алфавиту)": ('total_alphabetic', "Итоговое посещений на данный момент, отсортированное в алфавитном пордке"),
            "Итоговое (по возрастанию)": ('total_rated', "Итоговое посещений на данный момент, отсортированное в порядке возрастания процента посещений"),
            "Общий тренд": ('scatter', "Показывает итоговое посещение на данный момент и график тренда"),
            "Отклонения по дням": ("deviation", "Показывает изменение процента посещений относительно предыдущего дня")
        }
        self.items = []

        main_layout = QGridLayout()

        data_selector = QMComboBox(_DBRoot)
        main_layout.addWidget(QLabel('Данные по'), 0, 0)
        main_layout.addWidget(data_selector, 0, 1, 1, 2)

        item_selector = QMCheckedComboBox(self, with_all=True, type_=Student)
        item_selector_label = QLabel()
        # selector_layout.addWidget(item_selector_label, alignment=Qt.AlignVCenter | Qt.AlignRight)
        main_layout.addWidget(QLabel('Выбор'), 0, 3)
        main_layout.addWidget(item_selector, 0, 4, 1, 2)

        semester_selector = QMCheckedComboBox(self, False, Semester)
        main_layout.addWidget(QLabel('за'), 1, 0)
        main_layout.addWidget(semester_selector, 1, 1, 1, 2)
        semester_selector.loads(user)

        group_by_selector = QMComboBox(_DBRoot)
        group_by_selector.setEnabled(False)
        main_layout.addWidget(QLabel('Группировать'), 2, 0)
        group_by_checkbox = QCheckBox('включить')
        group_by_checkbox.stateChanged.connect(group_by_selector.setEnabled)
        main_layout.addWidget(group_by_checkbox, 2, 1, 1, 2)
        main_layout.addWidget(QLabel('по'), 2, 3)
        main_layout.addWidget(group_by_selector, 2, 4, 1, 2)

        plot_type_selector = QComboBox()

        main_layout.addWidget(QLabel('Тип'), 3, 0)
        main_layout.addWidget(plot_type_selector, 3, 1, 1, 2)

        description = QLabel()
        description.setWordWrap(True)
        main_layout.addWidget(QLabel('Описание'), 3, 3)
        main_layout.addWidget(description, 3, 4, 3, 2, Qt.AlignTop)

        plot_type_selector.currentTextChanged.connect(lambda x: description.setText(plot_types[x][1]))

        for i in range(6):
            main_layout.setRowStretch(i, 1)
        show_btn = QPushButton('Построить')
        show_btn.setEnabled(False)
        main_layout.addWidget(show_btn, 5, 2, 1, 2)

        def update_item_selector(index):
            item_selector.setEngine(data_selector.current())
            item_selector.clear()
            self.items = data_groups[index].of(user, sort=lambda x: x.full_name())
            item_selector.set_items(self.items)
            item_selector_label.setText(data_groups[index].__name__)
            show_btn.setEnabled(True)

        def update_semester_selector(items):
            semester_selector.clear()
            semester_selector.loads(items)

        def update_group_by_slector(index):
            group_by_selector.clear()
            group_by_selector.addItems([s for i, s in enumerate(data_groups) if i != index])

        data_selector.currentIndexChanged.connect(update_item_selector)
        item_selector.currentChanged.connect(update_semester_selector)
        data_selector.currentIndexChanged.connect(update_group_by_slector)

        data_selector.addItems([s for s in data_groups])

        def show():
            self.accept.emit(
                item_selector.current(),
                group_by_selector.current() if group_by_checkbox.isChecked() else data_selector.current(),
                plot_types[plot_type_selector.currentText()][0],
                semester_selector.current()
            )

        show_btn.clicked.connect(show)

        self.setLayout(main_layout)

        plot_type_selector.addItems(plot_types.keys())
Пример #6
0
    def __init__(self, professor: Professor):
        super().__init__()
        self.setObjectName("Selector")

        self.professor = professor

        main_layout = QVBoxLayout()

        self.tabs = QTabWidget()

        self.table = VisitTableWidget(self)
        self.tabs.addTab(self.table, "Таблица посещений")
        self.tabs.addTab(QWidget(), 'Задания (TODO)')

        selector_layout = QHBoxLayout()

        main_layout.addLayout(selector_layout, stretch=1)
        main_layout.addWidget(self.tabs, stretch=95)

        # semester
        self.semester = QMComboBox(parent=self, type_=Semester)
        sem_label = QLabel('Семестр')
        sem_label.setAlignment(Qt.AlignRight)

        selector_layout.addWidget(sem_label,
                                  1,
                                  alignment=Qt.AlignCenter | Qt.AlignRight)
        selector_layout.addWidget(self.semester, 2)

        # discipline
        self.discipline = QMComboBox(parent=self, type_=Discipline)
        disc_label = QLabel("Дисциплина")
        disc_label.setAlignment(Qt.AlignRight)

        selector_layout.addWidget(disc_label,
                                  1,
                                  alignment=Qt.AlignCenter | Qt.AlignRight)
        selector_layout.addWidget(self.discipline, 2)

        # group
        self.group = QMMultipleComboBox(parent=self, type_=Group)
        group_label = QLabel("Группа")
        group_label.setAlignment(Qt.AlignRight)

        selector_layout.addWidget(group_label,
                                  1,
                                  alignment=Qt.AlignCenter | Qt.AlignRight)
        selector_layout.addWidget(self.group, 2)

        # lesson
        self.lesson = QMComboBox(parent=self, type_=Lesson)
        lesson_label = QLabel("Занятие")
        lesson_label.setAlignment(Qt.AlignRight)

        selector_layout.addWidget(lesson_label,
                                  1,
                                  alignment=Qt.AlignCenter | Qt.AlignRight)
        selector_layout.addWidget(self.lesson, 2)

        self.start_button = QPushButton()
        self.start_button.setText("Начать занятие")

        self.end_button = QPushButton()
        self.end_button.setText("Завершить занятие")
        self.end_button.setVisible(False)

        selector_layout.addWidget(self.end_button, 2)
        selector_layout.addWidget(self.start_button, 2)

        self.setLayout(main_layout)

        selector_layout.setContentsMargins(0, 0, 0, 0)

        self.last_lesson = 0

        self.connect()
        self.semester.loads(self.professor)
Пример #7
0
class Selector(QWidget):
    reader_required = pyqtSignal('PyQt_PyObject')

    set_up = pyqtSignal('PyQt_PyObject')

    semester_changed = pyqtSignal('PyQt_PyObject')
    discipline_changed = pyqtSignal(
        'PyQt_PyObject')  # actual Signature (Discipline)
    group_changed = pyqtSignal(
        'PyQt_PyObject')  # actual signature (List[Group])
    lesson_changed = pyqtSignal('PyQt_PyObject')  # actual signature (Lesson)

    data_changed = pyqtSignal()
    lesson_started = pyqtSignal('PyQt_PyObject')
    lesson_finished = pyqtSignal()

    view_show_color_rate = pyqtSignal(
        bool)  # управляет цветовой подсветкой результатов студентов

    professor: Professor = None

    visitMarker: MarkVisitProcess = None

    def __init__(self, professor: Professor):
        super().__init__()
        self.setObjectName("Selector")

        self.professor = professor

        main_layout = QVBoxLayout()

        self.tabs = QTabWidget()

        self.table = VisitTableWidget(self)
        self.tabs.addTab(self.table, "Таблица посещений")
        self.tabs.addTab(QWidget(), 'Задания (TODO)')

        selector_layout = QHBoxLayout()

        main_layout.addLayout(selector_layout, stretch=1)
        main_layout.addWidget(self.tabs, stretch=95)

        # semester
        self.semester = QMComboBox(parent=self, type_=Semester)
        sem_label = QLabel('Семестр')
        sem_label.setAlignment(Qt.AlignRight)

        selector_layout.addWidget(sem_label,
                                  1,
                                  alignment=Qt.AlignCenter | Qt.AlignRight)
        selector_layout.addWidget(self.semester, 2)

        # discipline
        self.discipline = QMComboBox(parent=self, type_=Discipline)
        disc_label = QLabel("Дисциплина")
        disc_label.setAlignment(Qt.AlignRight)

        selector_layout.addWidget(disc_label,
                                  1,
                                  alignment=Qt.AlignCenter | Qt.AlignRight)
        selector_layout.addWidget(self.discipline, 2)

        # group
        self.group = QMMultipleComboBox(parent=self, type_=Group)
        group_label = QLabel("Группа")
        group_label.setAlignment(Qt.AlignRight)

        selector_layout.addWidget(group_label,
                                  1,
                                  alignment=Qt.AlignCenter | Qt.AlignRight)
        selector_layout.addWidget(self.group, 2)

        # lesson
        self.lesson = QMComboBox(parent=self, type_=Lesson)
        lesson_label = QLabel("Занятие")
        lesson_label.setAlignment(Qt.AlignRight)

        selector_layout.addWidget(lesson_label,
                                  1,
                                  alignment=Qt.AlignCenter | Qt.AlignRight)
        selector_layout.addWidget(self.lesson, 2)

        self.start_button = QPushButton()
        self.start_button.setText("Начать занятие")

        self.end_button = QPushButton()
        self.end_button.setText("Завершить занятие")
        self.end_button.setVisible(False)

        selector_layout.addWidget(self.end_button, 2)
        selector_layout.addWidget(self.start_button, 2)

        self.setLayout(main_layout)

        selector_layout.setContentsMargins(0, 0, 0, 0)

        self.last_lesson = 0

        self.connect()
        self.semester.loads(self.professor)

    def connect(self):
        self.semester.current_changed.connect(self.discipline.on_parent_change)

        self.discipline.current_changed.connect(self.group.on_parent_change)

        self.group.current_changed.connect(self.lesson.on_parent_change)
        self.group.current_changed.connect(self.table.setData)

        self.lesson.current_changed.connect(self.table.set_current_lesson)
        self.table.select_current_lesson.connect(self.lesson.setCurrent)

        self.start_button.clicked.connect(self.user_start_lesson)
        self.lesson_started.connect(self.start_lesson)
        self.lesson_started.connect(self.table.lesson_start)

        self.end_button.clicked.connect(self.user_stop_lesson)
        self.lesson_finished.connect(self.end_lesson)
        self.lesson_finished.connect(self.table.lesson_finish)

        self.view_show_color_rate.connect(self.table.view_show_color_rate)

    @pyqtSlot(bool, name='user_start_lesson')
    def user_start_lesson(self, status):
        students = Student.of(self.group.current())
        lesson = self.lesson.current()
        self.visit_marker = MarkVisitProcess(
            students, lesson, error_callback=self.lesson_finished.emit)
        self.visit_marker.new_visit.connect(self.table.new_visit)
        self.lesson_started.emit(lesson)

    @pyqtSlot(name='user_stop_lesson')
    def user_stop_lesson(self):
        self.lesson_finished.emit()

    def start_lesson(self):
        self.start_button.setVisible(False)
        self.end_button.setVisible(True)

        self.setEnabledControl(False)

        self._is_lesson_started = True

    def end_lesson(self):
        self.visit_marker.stop()
        self.start_button.setVisible(True)
        self.end_button.setVisible(False)

        self.setEnabledControl(True)

        self._is_lesson_started = False

    def setEnabledControl(self, b: bool):
        self.lesson.setEnabled(b)
        self.group.setEnabled(b)
        self.discipline.setEnabled(b)