class TimeEdit(QWidget): def __init__(self, parent, initial_time, label, on_update=lambda x: x): """ Args: parent: ColorMapWindow instance """ QWidget.__init__(self, parent) self.parent = parent self.on_update = on_update self.label = QLabel(label) self.qt_time = QTime.fromString(initial_time) self.time_edit = QTimeEdit(self.qt_time) self.time_edit.timeChanged.connect(self.update) self.grid = QGridLayout() self.fill_layout() self.setLayout(self.grid) @property def time(self): return self.qt_time.toPyTime().strftime('%H:%M') def fill_layout(self): grid = self.grid grid.addWidget(self.label, 0, 0) grid.addWidget(self.time_edit, 1, 0) @slot() def update(self): self.qt_time = self.time_edit.time() self.on_update(self.time) def update_constraint(self, min_time, max_time): pass
class SettingDialog(CenterMixin, QDialog): """Settings dialog.""" def __init__(self, parent=None): """Construct a settings dialog.""" super().__init__(parent) self.logger = logging.getLogger(__name__) self.logger.info('Opening setting dialog') self.setWindowTitle(self.tr('Edit preferences')) self.center() self.invalid_color = None self.valid_color = None self.current_cell_color = None self.__update_colors() week_time_label = QLabel(self.tr('Default week time'), self) self.week_time = DurationEdit(parent=self, hour_length=2) self.week_time.minutes = SettingModel.default_week_time() self.logger.info('Read default week time minutes: %s', SettingModel.default_week_time()) self.week_time.valueChanged.connect(self.__week_time_changed) man_day_time_label = QLabel(self.tr('Default man day time'), self) self.man_day_time = QTimeEdit(SettingModel.default_man_day_time(), self) self.logger.info('Read default man day time: %s', SettingModel.default_man_day_time().toString('hh:mm')) self.man_day_time.timeChanged.connect(self.__man_day_time_changed) invalid_color_label = QLabel(self.tr('Invalid color'), self) self.invalid_color_button = QPushButton(self.tr('Text'), self) self.invalid_color_button.clicked.connect( self.__open_invalid_color_dialog) valid_color_label = QLabel(self.tr('Valid color'), self) self.valid_color_button = QPushButton(self.tr('Text'), self) self.valid_color_button.clicked.connect(self.__open_valid_color_dialog) current_cell_color_label = QLabel(self.tr('Current cell color'), self) self.current_cell_color_button = QPushButton(self.tr('Text'), self) self.current_cell_color_button.clicked.connect( self.__open_current_cell_color_dialog) self.__update_buttons_colors() main_layout = QGridLayout() main_layout.addWidget(week_time_label, 0, 0) main_layout.addWidget(self.week_time, 0, 1) main_layout.addWidget(man_day_time_label, 1, 0) main_layout.addWidget(self.man_day_time, 1, 1) main_layout.addWidget(invalid_color_label, 2, 0) main_layout.addWidget(self.invalid_color_button, 2, 1) main_layout.addWidget(valid_color_label, 3, 0) main_layout.addWidget(self.valid_color_button, 3, 1) main_layout.addWidget(current_cell_color_label, 4, 0) main_layout.addWidget(self.current_cell_color_button, 4, 1) self.setLayout(main_layout) @pyqtSlot() def __week_time_changed(self): """Update the week time setting.""" SettingModel.set_default_week_time(self.week_time.minutes) self.logger.info('Write default week time minutes: %s', self.week_time.minutes) @pyqtSlot() def __man_day_time_changed(self): """Update the man day time setting.""" SettingModel.set_default_man_day_time(self.man_day_time.time()) self.logger.info('Write default man day time: %s', self.man_day_time.time().toString('hh:mm')) @pyqtSlot() def __open_invalid_color_dialog(self): """Update the invalid color setting.""" color = QColorDialog.getColor(self.invalid_color, self, self.tr('Select invalid color'), QColorDialog.DontUseNativeDialog) if color.isValid(): SettingModel.set_invalid_color(color) self.logger.info('Write invalid color: %s', color.name()) self.__update_colors() self.__update_buttons_colors() @pyqtSlot() def __open_valid_color_dialog(self): """Update the valid color setting.""" color = QColorDialog.getColor(self.valid_color, self, self.tr('Select invalid color'), QColorDialog.DontUseNativeDialog) if color.isValid(): SettingModel.set_valid_color(color) self.logger.info('Write valid color: %s', color.name()) self.__update_colors() self.__update_buttons_colors() @pyqtSlot() def __open_current_cell_color_dialog(self): """Update the current cell color setting.""" color = QColorDialog.getColor(self.current_cell_color, self, self.tr('Select current cell color'), QColorDialog.DontUseNativeDialog) if color.isValid(): SettingModel.set_current_cell_color(color) self.logger.info('Write current cell color: %s', color.name()) self.__update_colors() self.__update_buttons_colors() def __update_colors(self): """Update the local colors values.""" self.invalid_color = SettingModel.invalid_color() self.valid_color = SettingModel.valid_color() self.current_cell_color = SettingModel.current_cell_color() self.logger.info('Read invalid color: %s', self.invalid_color.name()) self.logger.info('Read valid color: %s', self.valid_color.name()) self.logger.info('Read current cell color: %s', self.current_cell_color.name()) def __update_buttons_colors(self): """Update the buttons colors.""" invalid_color = self.invalid_color.name() invalid_color_contrast = contrast_color(invalid_color) invalid_style = ('background-color:{}; color:{};'.format( invalid_color, invalid_color_contrast)) self.invalid_color_button.setStyleSheet(invalid_style) valid_color = self.valid_color.name() valid_color_contrast = contrast_color(valid_color) valid_style = ('background-color:{}; color:{};'.format( valid_color, valid_color_contrast)) self.valid_color_button.setStyleSheet(valid_style) current_cell_color = self.current_cell_color.name() current_cell_color_contrast = contrast_color(current_cell_color) current_cell_style = ('background-color:{}; color:{};'.format( current_cell_color, current_cell_color_contrast)) self.current_cell_color_button.setStyleSheet(current_cell_style)
class MediaCueGeneral(CueGeneral): Name = 'Cue Settings' def __init__(self, size, cue=None, parent=None): super().__init__(size, cue=cue, parent=parent) # Start at self.startGroup = QGroupBox(self) self.startGroup.setLayout(QHBoxLayout()) self.startEdit = QTimeEdit(self.startGroup) self.startEdit.setDisplayFormat('HH.mm.ss.zzz') self.startGroup.layout().addWidget(self.startEdit) self.startLabel = QLabel(self.startGroup) self.startLabel.setAlignment(QtCore.Qt.AlignCenter) self.startGroup.layout().addWidget(self.startLabel) self.layout().addWidget(self.startGroup) # Loop self.loopGroup = QGroupBox(self) self.loopGroup.setLayout(QHBoxLayout()) self.spinLoop = QSpinBox(self.loopGroup) self.spinLoop.setRange(-1, 1000000) self.loopGroup.layout().addWidget(self.spinLoop) self.loopLabel = QLabel(self.loopGroup) self.loopLabel.setAlignment(QtCore.Qt.AlignCenter) self.loopGroup.layout().addWidget(self.loopLabel) self.layout().addWidget(self.loopGroup) # Checks self.checkPause = QCheckBox(self) self.layout().addWidget(self.checkPause) self.retranslateUi() def retranslateUi(self): self.startGroup.setTitle('Start time') self.startLabel.setText('Amount of skip time') self.loopGroup.setTitle("Loop") self.loopLabel.setText("Repetition after first play (-1 = infinite)") self.checkPause.setText("Enable Pause") def get_configuration(self): conf = super().get_configuration() conf['media'] = {} checkable = self.startGroup.isCheckable() if not (checkable and not self.startGroup.isChecked()): time = self.startEdit.time().msecsSinceStartOfDay() conf['media']['start_at'] = time if not (checkable and not self.loopGroup.isChecked()): conf['media']['loop'] = self.spinLoop.value() if self.checkPause.checkState() != QtCore.Qt.PartiallyChecked: conf['pause'] = self.checkPause.isChecked() return conf def enable_check(self, enable): super().enable_check(enable) self.startGroup.setCheckable(enable) self.startGroup.setChecked(False) self.loopGroup.setCheckable(enable) self.loopGroup.setChecked(False) self.checkPause.setTristate(enable) if enable: self.checkPause.setCheckState(QtCore.Qt.PartiallyChecked) def set_configuration(self, conf): super().set_configuration(conf) if 'pause' in conf: self.checkPause.setChecked(conf['pause']) if 'media' in conf: if 'loop' in conf['media']: self.spinLoop.setValue(conf['media']['loop']) if 'duration' in conf['media'] and conf['media']['duration'] > 0: t = QTime().fromMSecsSinceStartOfDay(conf['media']['duration']) self.startEdit.setMaximumTime(t) if 'start_at' in conf['media']: t = QTime().fromMSecsSinceStartOfDay(conf['media']['start_at']) self.startEdit.setTime(t)
class spectral2_gui(QWidget): def __init__(self): super().__init__() top_hbox = QHBoxLayout() top_widget = QWidget() #top_widget.setLayout(top_hbox) self.plot = plot_widget(enable_toolbar=False) #self.plot.load_data(["jv.dat"]) #self.plot.set_labels(["jv.dat"]) self.plot.do_plot() #self.plot.fig.canvas.draw() date_widget = QWidget() date_vbox = QVBoxLayout() self.cal = QCalendarWidget(self) self.cal.setGridVisible(True) self.cal.move(10, 20) self.time = QTimeEdit() time = QTime(12, 30) self.time.setTime(time) date_vbox.addWidget(self.cal) date_vbox.addWidget(self.time) self.lat_widget = QWidget() self.lat_layout = QHBoxLayout() self.lat_label = QLabel("Latitude") self.lat_edit = QLineEdit() self.lat_layout.addWidget(self.lat_label) self.lat_layout.addWidget(self.lat_edit) self.lat_widget.setLayout(self.lat_layout) date_vbox.addWidget(self.lat_widget) self.preasure_widget = QWidget() self.preasure_layout = QHBoxLayout() self.preasure_label = QLabel("Preasure (bar)") self.preasure_edit = QLineEdit() self.preasure_layout.addWidget(self.preasure_label) self.preasure_layout.addWidget(self.preasure_edit) self.preasure_widget.setLayout(self.preasure_layout) date_vbox.addWidget(self.preasure_widget) self.aod_widget = QWidget() self.aod_layout = QHBoxLayout() self.aod_label = QLabel("AOD (cm-1)") self.aod_edit = QLineEdit() self.aod_layout.addWidget(self.aod_label) self.aod_layout.addWidget(self.aod_edit) self.aod_widget.setLayout(self.aod_layout) date_vbox.addWidget(self.aod_widget) self.water_widget = QWidget() self.water_layout = QHBoxLayout() self.water_label = QLabel("Water (cm-1)") self.water_edit = QLineEdit() self.water_layout.addWidget(self.water_label) self.water_layout.addWidget(self.water_edit) self.water_widget.setLayout(self.water_layout) date_vbox.addWidget(self.water_widget) self.no2_widget = QWidget() self.no2_layout = QHBoxLayout() self.no2_label = QLabel("NO2 (cm-1)") self.no2_edit = QLineEdit() self.no2_layout.addWidget(self.no2_label) self.no2_layout.addWidget(self.no2_edit) self.no2_widget.setLayout(self.no2_layout) if am_i_rod() == True: date_vbox.addWidget(self.no2_widget) date_widget.setLayout(date_vbox) top_hbox.addWidget(self.plot) top_hbox.addWidget(date_widget) self.setLayout(top_hbox) #inp_get_token_value("spectral2.inp","#spectral2_day") #inp_get_token_value("spectral2.inp","#spectral2_hour") #inp_get_token_value("spectral2.inp","#spectral2_minute") self.water_edit.setText( inp_get_token_value("spectral2.inp", "#spectral2_water")) self.aod_edit.setText( inp_get_token_value("spectral2.inp", "#spectral2_aod")) self.preasure_edit.setText( inp_get_token_value("spectral2.inp", "#spectral2_preasure")) self.lat_edit.setText( inp_get_token_value("spectral2.inp", "#spectral2_lat")) self.no2_edit.setText( inp_get_token_value("spectral2.inp", "#spectral2_no2")) self.calculate() def calculate(self): self.plot.data = [] self.water_edit.text() day = self.cal.selectedDate().dayOfYear() hour = self.time.time().hour() minute = self.time.time().minute() inp_update_token_value("spectral2.inp", "#spectral2_day", str(day)) inp_update_token_value("spectral2.inp", "#spectral2_hour", str(hour)) inp_update_token_value("spectral2.inp", "#spectral2_minute", str(minute)) inp_update_token_value("spectral2.inp", "#spectral2_lat", self.lat_edit.text()) inp_update_token_value("spectral2.inp", "#spectral2_aod", self.aod_edit.text()) inp_update_token_value("spectral2.inp", "#spectral2_preasure", self.preasure_edit.text()) inp_update_token_value("spectral2.inp", "#spectral2_water", self.water_edit.text()) inp_update_token_value("spectral2.inp", "#spectral2_no2", self.no2_edit.text()) s = spectral2() s.calc() am = dat_file() am.load(os.path.join(get_spectra_path(), "AM1.5G", "spectra.inp")) am.key_text = "AM1.5G" self.plot.data.append(am) self.plot.data.append(s.Iglobal) self.plot.data.append(s.Id) self.plot.data.append(s.Is) self.plot.norm_data() self.plot.do_plot()
class QStudyingView(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.time_label = QLabel("Время начала", self) self.time_edit = QTimeEdit() self.date_label = QLabel("Дата", parent=self) self.date_edit = QDateEdit(calendarPopup=True) self.subjects_label = QLabel("Темы", self) self.subjects_list = QListWidget(self) layout = QVBoxLayout() layout.addWidget(self.time_label) layout.addWidget(self.time_edit) layout.addWidget(self.date_label) layout.addWidget(self.date_edit) layout.addWidget(self.subjects_label) layout.addWidget(self.subjects_list) self.ok_btn = QPushButton('OK', parent=self) self.ok_btn.clicked.connect(self.ok) self.ok_cancel = QPushButton('Cancel', parent=self) self.ok_cancel.clicked.connect(self.cancel) btn_layout = QHBoxLayout() btn_layout.addWidget(self.ok_btn) btn_layout.addWidget(self.ok_cancel) layout.addLayout(btn_layout) layout.addStretch(0) self.setLayout(layout) self.presenter = StudyingPresenter(self) def set_subject_items(self, items: str): for i in items: item = QListWidgetItem(i) item.setCheckState(Qt.Unchecked) self.subjects_list.addItem(item) def set_subjects(self, subjects): if not subjects: return for i in subjects: self.subjects_list.findItems(i, Qt.MatchFixedString)[0].setData( Qt.CheckStateRole, Qt.Checked) def get_subjects(self): return [ self.subjects_list.item(i).text() for i in range(self.subjects_list.count()) if self.subjects_list.item(i).checkState() == Qt.Checked ] def get_time(self): return self.time_edit.time().toPyTime() def set_time(self, value): if value is not None: self.time_edit.setTime(value) def get_date(self): return self.date_edit.date().toPyDate() def set_date(self, value): if value is not None: self.date_edit.setTime(value) def ok(self): self.presenter.ok() def cancel(self): self.presenter.cancel() def get_presenter(self): return self.presenter
class ReportGen(PageWindow): def __init__(self): super().__init__() self.initUI() self.createWidgets() def initUI(self): self.setWindowTitle("Report Generation") self.setFixedSize(400, 590) # Set the central widget and the general layout self.generalLayout = QVBoxLayout() self._centralWidget = QWidget(self) self.setCentralWidget(self._centralWidget) self._centralWidget.setLayout(self.generalLayout) def createWidgets(self): self.logSelector=QComboBox(self) self.logSelector.resize(110,40) self.logSelector.move(140,40) self.logSelector.addItem("Resident Log") self.logSelector.addItem("Visitor Log") self.datepicker=QDateEdit(self) self.datepicker.setCalendarPopup(True) self.datepicker.move(145,120) self.datepicker.setDate(dt.today()) self.startTime=QTimeEdit(self) self.startTime.move(65,200) self.endTime=QTimeEdit(self) self.endTime.move(225,200) self.genButton=QPushButton("Generate",self) self.genButton.move(145,280) self.backButton=QPushButton("Back",self) self.backButton.move(145,340) self.backButton.clicked.connect(self.goBack) self.genButton.clicked.connect(self.repGen) def goBack(self): self.goto("welcome") def repGen(self): #print("Hey") log=self.logSelector.currentText() date=str(self.datepicker.date().toPyDate()) #print(date) start=str(self.startTime.time().toPyTime()) end=str(self.endTime.time().toPyTime()) vbox=QVBoxLayout() table=QTableWidget() #print("Heyo") #print(log+" "+date+" "+start+" "+end) repList=getRepData(log,date,start,end) rows=len(repList) print(repList) table.setRowCount(rows+1) if(log=="Resident Log"): #print("hey") table.setColumnCount(4) table.setItem(0,0,QTableWidgetItem("Vehicle No.")) table.setItem(0,1,QTableWidgetItem("Flat No.")) table.setItem(0,2,QTableWidgetItem("Entry Time")) table.setItem(0,3,QTableWidgetItem("Exit Time")) table.resize(650,400) else: table.setColumnCount(5) table.setItem(0,0,QTableWidgetItem("Vehicle No.")) table.setItem(0,1,QTableWidgetItem("Visitor Name")) table.setItem(0,2,QTableWidgetItem("Flat No.")) table.setItem(0,3,QTableWidgetItem("Entry Time")) table.setItem(0,4,QTableWidgetItem("Exit Time")) table.resize(800,400) try: i=1 j=0 for row in repList: for j in range(len(row)): #print(j+" "+row[j]) table.setItem(i,j,QTableWidgetItem(row[j])) i+=1 except Exception as e: print(e) table.horizontalHeader().setDefaultSectionSize(155) table.show() vbox.addWidget(table) self.setLayout(vbox)
class TimeFrame(BaseFrame): time_hacked = pyqtSignal() def __init__(self, is_mission, parent=None): super().__init__(parent) # Setup frame self.label.setText("Time:") zulu_label = QLabel("ZULU") zulu_label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.time_edit = QTimeEdit() self.time_edit.setDisplayFormat("HH:mm:ss") self.hack_btn = QPushButton("Hack") self.hack_btn.setAutoDefault(False) if is_mission: self.hack_btn.setStyleSheet("background-color: red; color: white;") else: self.hack_btn.setStyleSheet( "background-color: gray; color: white;") self.sys_time_btn = QPushButton("Use System Time") self.sys_time_btn.setAutoDefault(False) if not is_mission: self.time_edit.setEnabled(False) self.hack_btn.setEnabled(False) self.sys_time_btn.setEnabled(False) self.layout.addWidget(self.label) self.layout.addWidget(self.time_edit) self.layout.addWidget(zulu_label) self.layout.addWidget(self.hack_btn) self.layout.addWidget(self.sys_time_btn) self.setLayout(self.layout) # Setup behavior self.time = QTime() self.hack_timer = QTimer() self.hack_timer.setTimerType(Qt.VeryCoarseTimer) self.hack_timer.setInterval(1000) self.hack_timer.timeout.connect(self.inc_time) self.hack_btn.clicked.connect(self.hack_time) self.sys_time_btn.clicked.connect(self.set_sys_time) @pyqtSlot() def hack_time(self, sys_time=None): if not self.hack_timer.isActive(): self.time = self.time_edit.time() if not sys_time else sys_time self.hack_timer.start() self.time_edit.setTime(self.time) self.hack_btn.setStyleSheet( "background-color: green; color: white;") self.hack_btn.setText("Hacked!") self.time_edit.setEnabled(False) self.sys_time_btn.setEnabled(False) else: self.hack_btn.setStyleSheet("background-color: red; color: white;") self.hack_btn.setText("Hack") self.hack_timer.stop() self.time_edit.setEnabled(True) self.sys_time_btn.setEnabled(True) self.time_hacked.emit() @pyqtSlot() def set_sys_time(self): self.hack_time(QTime().currentTime()) @pyqtSlot() def inc_time(self): self.time = self.time.addSecs(1) self.time_edit.setTime(self.time)
class SeekSettings(SettingsPage): Name = 'Seek Settings' def __init__(self, **kwargs): super().__init__(**kwargs) self.cue_id = -1 self.setLayout(QVBoxLayout(self)) self.cueDialog = CueListDialog( cues=Application().cue_model.filter(MediaCue), parent=self) self.cueGroup = QGroupBox(self) self.cueGroup.setLayout(QVBoxLayout()) self.layout().addWidget(self.cueGroup) self.cueButton = QPushButton(self.cueGroup) self.cueButton.clicked.connect(self.select_cue) self.cueGroup.layout().addWidget(self.cueButton) self.cueLabel = QLabel(self.cueGroup) self.cueLabel.setAlignment(QtCore.Qt.AlignCenter) self.cueGroup.layout().addWidget(self.cueLabel) self.seekGroup = QGroupBox(self) self.seekGroup.setLayout(QHBoxLayout()) self.layout().addWidget(self.seekGroup) self.seekEdit = QTimeEdit(self.seekGroup) self.seekEdit.setDisplayFormat('HH.mm.ss.zzz') self.seekGroup.layout().addWidget(self.seekEdit) self.seekLabel = QLabel(self.seekGroup) self.seekLabel.setAlignment(QtCore.Qt.AlignCenter) self.seekGroup.layout().addWidget(self.seekLabel) self.layout().addSpacing(200) self.retranslateUi() def retranslateUi(self): self.cueGroup.setTitle('Cue') self.cueButton.setText('Click to select') self.cueLabel.setText('Not selected') self.seekGroup.setTitle('Seek') self.seekLabel.setText('Time to reach') def select_cue(self): if self.cueDialog.exec_() == self.cueDialog.Accepted: cue = self.cueDialog.selected_cues()[0] self.cue_id = cue.id self.seekEdit.setMaximumTime( QTime.fromMSecsSinceStartOfDay(cue.media.duration)) self.cueLabel.setText(cue.name) def enable_check(self, enabled): self.cueGroup.setCheckable(enabled) self.cueGroup.setChecked(False) self.seekGroup.setCheckable(enabled) self.seekGroup.setChecked(False) def get_settings(self): return {'target_id': self.cue_id, 'time': self.seekEdit.time().msecsSinceStartOfDay()} def load_settings(self, settings): if settings is not None: cue = Application().cue_model.get(settings['target_id']) if cue is not None: self.cue_id = settings['target_id'] self.seekEdit.setTime( QTime.fromMSecsSinceStartOfDay(settings['time'])) self.seekEdit.setMaximumTime( QTime.fromMSecsSinceStartOfDay(cue.media.duration)) self.cueLabel.setText(cue.name)
class SceneSchedulingTab(QWidget): def __init__(self): super().__init__() self._res = ResourceManager() self._cbox_type = QComboBox() self._check_day = list() days = self._res['days'].split(', ') for day in days: self._check_day.append(QCheckBox(day)) self._time_from = QTimeEdit() self._time_to = QTimeEdit() self.init_ui() @staticmethod def schedule_type_to_text(schedule_type: ScheduleType) -> str: return schedule_type.name.capitalize().replace('_', ' ') @staticmethod def text_to_schedule_type(text: str) -> ScheduleType: return ScheduleType[text.upper().replace(' ', '_')] def load_data_on_ui(self, scene: Scene) -> None: schedule = scene.schedule type_text = self.schedule_type_to_text(schedule.type) idx = self._cbox_type.findText(type_text) self._cbox_type.setCurrentIndex(idx) for i in range(7): self._check_day[i].setChecked(schedule.day_of_week[i]) self._time_from.setTime(schedule.from_time) self._time_to.setTime(schedule.to_time) def init_ui(self) -> None: schedule_type = [ self.schedule_type_to_text(ScheduleType.ALWAYS_HIDDEN), self.schedule_type_to_text(ScheduleType.ALWAYS_VISIBLE), self.schedule_type_to_text(ScheduleType.HIDDEN_ON_TIME), self.schedule_type_to_text(ScheduleType.VISIBLE_ON_TIME) ] self._cbox_type.addItems(schedule_type) vbox_schedule_type = QVBoxLayout() vbox_schedule_type.addWidget(self._cbox_type) group_schedule_type = QGroupBox(self._res['scheduleTypeLabel']) group_schedule_type.setLayout(vbox_schedule_type) hbox_day = QHBoxLayout() for i in range(len(self._check_day)): hbox_day.addWidget(self._check_day[i]) group_day = QGroupBox(self._res['dayLabel']) group_day.setLayout(hbox_day) self._time_from.setDisplayFormat("HH:mm:ss") self._time_to.setDisplayFormat("HH:mm:ss") hbox_time = QHBoxLayout() hbox_time.addWidget(self._time_from) hbox_time.addWidget(QLabel('to')) hbox_time.addWidget(self._time_to) hbox_time.addStretch(1) group_time = QGroupBox(self._res['timeLabel']) group_time.setLayout(hbox_time) vbox_outmost = QVBoxLayout() vbox_outmost.addWidget(group_schedule_type) vbox_outmost.addWidget(group_day) vbox_outmost.addWidget(group_time) vbox_outmost.addStretch(1) self.setLayout(vbox_outmost) def save(self, scene: Scene) -> None: scene.schedule.type = self.text_to_schedule_type( self._cbox_type.currentText()) day_of_week = list() for i in range(len(self._check_day)): day_of_week.append(self._check_day[i].isChecked()) scene.schedule.day_of_week = day_of_week scene.schedule.from_time = self._time_from.time().toPyTime() scene.schedule.to_time = self._time_to.time().toPyTime() def is_data_valid(self) -> bool: return self._time_from.time() < self._time_to.time()
class TaskAddEditor(QDialog): #initialize everything def __init__(self, dialog_name, button_name, identifier=None): super(TaskAddEditor, self).__init__() self.dialog_name = dialog_name self.button_name = button_name self.identifier = identifier self.setGeometry(50, 50, 300, 250) self.tabs = QTabWidget() self.tabs.tab_1 = QWidget() self.tabs.tab_2 = QWidget() self.tabs.addTab(self.tabs.tab_1, "Basic Info") self.tabs.addTab(self.tabs.tab_2, "Notifications") self.tab_1() self.tab_2() main_layout = QVBoxLayout() main_layout.addWidget(self.tabs) buttons = QHBoxLayout() button_ok = QPushButton(self.button_name) button_close = QPushButton("Cancel") button_ok.clicked.connect(self.dialog_button_click) button_close.clicked.connect(self.dialog_cancel_click) buttons.addWidget(button_ok) buttons.addWidget(button_close) main_layout.addLayout(buttons) self.setLayout(main_layout) self.setWindowTitle(dialog_name) self.exec_() def tab_1(self): # main layout layout = QVBoxLayout() task_name = QLabel('Task Name') due_date = QLabel('Due Date') due_time = QLabel('Due Time') if (self.button_name == "Add"): self.task_name_input = QLineEdit() self.due_date_input = QDateEdit() self.due_date_input.setMinimumDate(QDate.currentDate()) self.due_time_input = QTimeEdit() else: task_info = user_tasks.get_task(self.identifier) self.task_name_input = QLineEdit(task_info[1]) self.due_date_input = QDateEdit(task_info[2].date()) self.due_date_input.setMinimumDate(QDate.currentDate()) self.due_time_input = QTimeEdit(task_info[2].time()) layout.addWidget(task_name) layout.addWidget(self.task_name_input) layout.addWidget(due_date) layout.addWidget(self.due_date_input) layout.addWidget(due_time) layout.addWidget(self.due_time_input) layout.addSpacing(20) self.tabs.tab_1.setLayout(layout) def tab_2(self): layout = QVBoxLayout() page_name = QLabel('Notification Settings') layout.addWidget(page_name) add_notification_area = QHBoxLayout() description = QLabel('Remind Me Everyday At: ') self.time_input = QTimeEdit() add_notification = QPushButton('+') add_notification.setFixedSize(30, 30) add_notification.clicked.connect(self.add_notification) add_notification_area.addWidget(description) add_notification_area.addWidget(self.time_input) add_notification_area.addWidget(add_notification) layout.addLayout(add_notification_area) your_notifications = QLabel('Your Notifications:') layout.addWidget(your_notifications) #create a scroll area to hold notifications notifications_area = QScrollArea(self) notifications_area.setWidgetResizable(True) widget = QWidget() notifications_area.setWidget(widget) self.notifications_layout = QVBoxLayout(widget) notifications_area.setAlignment(Qt.AlignTop) self.notifications_layout.setAlignment(Qt.AlignTop) layout.addWidget(notifications_area) if self.identifier is not None: #get a list of datetime objects notifications = user_tasks.get_notifications(self.identifier) #add notifications to the tab for notification_date in notifications: self.notifications_layout.addWidget( Notification(notification_date)) self.tabs.tab_2.setLayout(layout) def add_notification(self): # adds a notification to the layout of notifications for index in range(self.notifications_layout.count()): if ((self.notifications_layout.itemAt( index).widget().notification_time) > (self.time_input.time().toPyTime())): self.notifications_layout.insertWidget( index, Notification(self.time_input.time().toPyTime())) return elif (self.notifications_layout.itemAt(index).widget(). notification_time) == self.time_input.time().toPyTime(): error = QMessageBox() error.setText("Time Already Set") error.exec_() return self.notifications_layout.addWidget( Notification(self.time_input.time().toPyTime())) def dialog_button_click(self): # when add is pressed if (input_error_box(self.due_time_input, self.due_date_input, self.task_name_input)): notification_dates = [] for notification in range(self.notifications_layout.count()): notification_dates.append( self.notifications_layout.itemAt( notification).widget().notification_time) if (self.button_name == 'Add'): print(notification_dates) user_tasks.add_task( self.task_name_input.text(), datetime.combine(self.due_date_input.date().toPyDate(), self.due_time_input.time().toPyTime()), datetime.today(), str(uuid.uuid4()), notification_dates) else: print(notification_dates) user_tasks.edit_task( self.identifier, self.task_name_input.text(), datetime.combine(self.due_date_input.date().toPyDate(), self.due_time_input.time().toPyTime()), notification_dates) self.reject() gui_window.refresh_tasks() def dialog_cancel_click(self): #used in the input window and closes it self.reject()
class TimekeepingPropertiesDialog(QDialog): def __init__(self): super().__init__(GlobalAccess().get_main_window()) self.time_format = 'hh:mm:ss' def exec(self): self.init_ui() return super().exec() def init_ui(self): # self.setFixedWidth(500) self.setWindowTitle(_('Timekeeping settings')) # self.setWindowIcon(QIcon(icon_dir('sportident.png'))) self.setSizeGripEnabled(False) self.setModal(True) self.tab_widget = QTabWidget() # timekeeping tab self.timekeeping_tab = QWidget() self.tk_layout = QFormLayout() self.label_zero_time = QLabel(_('Zero time')) self.item_zero_time = QTimeEdit() self.item_zero_time.setDisplayFormat("HH:mm") self.item_zero_time.setMaximumSize(60, 20) self.item_zero_time.setDisabled(True) self.tk_layout.addRow(self.label_zero_time, self.item_zero_time) self.label_si_port = QLabel(_('Available Ports')) self.item_si_port = AdvComboBox() self.item_si_port.addItems(SIReaderClient().get_ports()) self.tk_layout.addRow(self.label_si_port, self.item_si_port) self.start_group_box = QGroupBox(_('Start time')) self.start_layout = QFormLayout() self.item_start_protocol = QRadioButton(_('From protocol')) self.start_layout.addRow(self.item_start_protocol) self.item_start_station = QRadioButton(_('Start station')) self.start_layout.addRow(self.item_start_station) self.item_start_cp = QRadioButton(_('Control point')) self.item_start_cp_value = QSpinBox() self.item_start_cp_value.setMaximumSize(60, 20) self.start_layout.addRow(self.item_start_cp, self.item_start_cp_value) self.item_start_gate = QRadioButton(_('Start gate')) self.item_start_gate.setDisabled(True) self.start_layout.addRow(self.item_start_gate) self.start_group_box.setLayout(self.start_layout) self.tk_layout.addRow(self.start_group_box) self.finish_group_box = QGroupBox(_('Finish time')) self.finish_layout = QFormLayout() self.item_finish_station = QRadioButton(_('Finish station')) self.finish_layout.addRow(self.item_finish_station) self.item_finish_cp = QRadioButton(_('Control point')) self.item_finish_cp_value = QSpinBox() self.item_finish_cp_value.setMinimum(-1) self.item_finish_cp_value.setMaximumSize(60, 20) self.finish_layout.addRow(self.item_finish_cp, self.item_finish_cp_value) self.item_finish_beam = QRadioButton(_('Light beam')) self.item_finish_beam.setDisabled(True) self.finish_layout.addRow(self.item_finish_beam) self.finish_group_box.setLayout(self.finish_layout) self.tk_layout.addRow(self.finish_group_box) self.chip_reading_box = QGroupBox(_('Assigning a chip when reading')) self.chip_reading_layout = QFormLayout() self.chip_reading_off = QRadioButton(_('Off')) self.chip_reading_layout.addRow(self.chip_reading_off) self.chip_reading_unknown = QRadioButton(_('Only unknown members')) self.chip_reading_layout.addRow(self.chip_reading_unknown) self.chip_reading_always = QRadioButton(_('Always')) self.chip_reading_layout.addRow(self.chip_reading_always) self.chip_reading_box.setLayout(self.chip_reading_layout) self.tk_layout.addRow(self.chip_reading_box) self.assignment_mode = QCheckBox(_('Assignment mode')) self.assignment_mode.stateChanged.connect(self.on_assignment_mode) self.tk_layout.addRow(self.assignment_mode) self.timekeeping_tab.setLayout(self.tk_layout) # result processing tab self.result_proc_tab = QWidget() self.result_proc_layout = QFormLayout() self.rp_time_radio = QRadioButton(_('by time')) self.result_proc_layout.addRow(self.rp_time_radio) self.rp_scores_radio = QRadioButton(_('by scores')) self.rp_scores_radio.setDisabled(True) # TODO self.result_proc_layout.addRow(self.rp_scores_radio) self.rp_scores_group = QGroupBox() self.rp_scores_group.setDisabled(True) # TODO self.rp_scores_layout = QFormLayout(self.rp_scores_group) self.rp_rogain_scores_radio = QRadioButton(_('rogain scores')) self.rp_scores_layout.addRow(self.rp_rogain_scores_radio) self.rp_fixed_scores_radio = QRadioButton(_('fixed scores')) self.rp_fixed_scores_edit = QSpinBox() self.rp_fixed_scores_edit.setMaximumWidth(50) self.rp_scores_layout.addRow(self.rp_fixed_scores_radio, self.rp_fixed_scores_edit) self.rp_scores_minute_penalty_label = QLabel(_('minute penalty')) self.rp_scores_minute_penalty_edit = QSpinBox() self.rp_scores_minute_penalty_edit.setMaximumWidth(50) self.rp_scores_layout.addRow(self.rp_scores_minute_penalty_label, self.rp_scores_minute_penalty_edit) self.result_proc_layout.addRow(self.rp_scores_group) self.result_proc_tab.setLayout(self.result_proc_layout) # marked route settings self.marked_route_tab = QWidget() self.mr_layout = QFormLayout() self.mr_off_radio = QRadioButton(_('no penalty')) self.mr_layout.addRow(self.mr_off_radio) self.mr_time_radio = QRadioButton(_('penalty time')) self.mr_time_edit = QTimeEdit() self.mr_time_edit.setDisplayFormat(self.time_format) self.mr_layout.addRow(self.mr_time_radio, self.mr_time_edit) self.mr_laps_radio = QRadioButton(_('penalty laps')) self.mr_layout.addRow(self.mr_laps_radio) self.mr_counting_lap_check = QCheckBox(_('counting lap')) self.mr_counting_lap_check.setDisabled(True) # TODO self.mr_layout.addRow(self.mr_counting_lap_check) self.mr_lap_station_check = QCheckBox(_('lap station')) self.mr_lap_station_check.setDisabled(True) # TODO self.mr_lap_station_edit = QSpinBox() self.mr_lap_station_edit.setMaximumWidth(50) self.mr_layout.addRow(self.mr_lap_station_check, self.mr_lap_station_edit) self.marked_route_tab.setLayout(self.mr_layout) # scores """ Scores [ x ] scores array 40, 37, 35, 33, ... 2, 1 [ Edit ] [ ] scores formula 1000 - 1000 * result / leader [ Edit ] """ self.scores_tab = QWidget() self.scores_layout = QFormLayout() self.scores_off = QRadioButton(_('scores off')) self.scores_array = QRadioButton(_('scores array')) self.scores_array_edit = QLineEdit() self.scores_formula = QRadioButton(_('scores formula')) self.scores_formula_edit = QLineEdit() self.scores_formula_hint = QLabel(_('scores formula hint')) self.scores_formula_hint.setWordWrap(True) self.scores_layout.addRow(self.scores_off) self.scores_layout.addRow(self.scores_array) self.scores_layout.addRow(self.scores_array_edit) self.scores_layout.addRow(self.scores_formula) self.scores_layout.addRow(self.scores_formula_edit) self.scores_layout.addRow(self.scores_formula_hint) self.scores_tab.setLayout(self.scores_layout) # time settings self.time_settings_tab = QWidget() self.time_settings_layout = QFormLayout() self.time_settings_accuracy_label = QLabel(_('Accuracy')) self.time_settings_accuracy_edit = QSpinBox() self.time_settings_accuracy_edit.setMaximumWidth(50) self.time_settings_accuracy_edit.setMaximum(3) self.time_settings_layout.addRow(self.time_settings_accuracy_label, self.time_settings_accuracy_edit) self.time_settings_format = QGroupBox() self.time_settings_format.setTitle(_('Format of competitions')) self.time_settings_format_less = QRadioButton(_('< 24')) self.time_settings_format_more = QRadioButton(_('> 24')) self.time_settings_format_layout = QFormLayout() self.time_settings_format_layout.addRow(self.time_settings_format_less) self.time_settings_format_layout.addRow(self.time_settings_format_more) self.time_settings_format.setLayout(self.time_settings_format_layout) self.time_settings_layout.addRow(self.time_settings_format) self.time_settings_tab.setLayout(self.time_settings_layout) self.tab_widget.addTab(self.timekeeping_tab, _('SPORTident (Sportiduino, ...) settings')) self.tab_widget.addTab(self.result_proc_tab, _('Result processing')) self.tab_widget.addTab(self.scores_tab, _('Scores')) self.tab_widget.addTab(self.marked_route_tab, _('Penalty calculation')) self.tab_widget.addTab(self.time_settings_tab, _('Time settings')) def cancel_changes(): self.close() def apply_changes(): try: self.apply_changes_impl() except Exception as e: logging.error(str(e)) self.close() button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.button_ok = button_box.button(QDialogButtonBox.Ok) self.button_ok.setText(_('OK')) self.button_ok.clicked.connect(apply_changes) self.button_cancel = button_box.button(QDialogButtonBox.Cancel) self.button_cancel.setText(_('Cancel')) self.button_cancel.clicked.connect(cancel_changes) self.layout = QFormLayout(self) self.layout.addRow(self.tab_widget) self.layout.addRow(button_box) self.set_values_from_model() self.show() def on_assignment_mode(self): mode = False if self.assignment_mode.isChecked(): mode = True self.start_group_box.setDisabled(mode) self.finish_group_box.setDisabled(mode) self.chip_reading_box.setDisabled(mode) def set_values_from_model(self): cur_race = race() zero_time = cur_race.get_setting('system_zero_time', (8, 0, 0)) start_source = cur_race.get_setting('system_start_source', 'protocol') start_cp_number = cur_race.get_setting('system_start_cp_number', 31) finish_source = cur_race.get_setting('system_finish_source', 'station') finish_cp_number = cur_race.get_setting('system_finish_cp_number', 90) assign_chip_reading = cur_race.get_setting('system_assign_chip_reading', 'off') assignment_mode = cur_race.get_setting('system_assignment_mode', False) si_port = cur_race.get_setting('system_port', '') self.item_zero_time.setTime(QTime(zero_time[0], zero_time[1])) self.item_si_port.setCurrentText(si_port) if start_source == 'protocol': self.item_start_protocol.setChecked(True) elif start_source == 'station': self.item_start_station.setChecked(True) elif start_source == 'cp': self.item_start_cp.setChecked(True) elif start_source == 'gate': self.item_start_gate.setChecked(True) self.item_start_cp_value.setValue(start_cp_number) if finish_source == 'station': self.item_finish_station.setChecked(True) elif finish_source == 'cp': self.item_finish_cp.setChecked(True) elif finish_source == 'beam': self.item_finish_beam.setChecked(True) self.item_finish_cp_value.setValue(finish_cp_number) if assign_chip_reading == 'off': self.chip_reading_off.setChecked(True) elif assign_chip_reading == 'only_unknown_members': self.chip_reading_unknown.setChecked(True) elif assign_chip_reading == 'always': self.chip_reading_always.setChecked(True) self.assignment_mode.setChecked(assignment_mode) # result processing obj = cur_race rp_mode = obj.get_setting('result_processing_mode', 'time') rp_score_mode = obj.get_setting('result_processing_score_mode', 'rogain') rp_fixed_scores_value = obj.get_setting('result_processing_fixed_score_value', 1) rp_scores_minute_penalty = obj.get_setting('result_processing_scores_minute_penalty', 1) if rp_mode == 'time': self.rp_time_radio.setChecked(True) else: self.rp_scores_radio.setChecked(True) if rp_score_mode == 'rogain': self.rp_rogain_scores_radio.setChecked(True) else: self.rp_fixed_scores_radio.setChecked(True) self.rp_fixed_scores_edit.setValue(rp_fixed_scores_value) self.rp_scores_minute_penalty_edit.setValue(rp_scores_minute_penalty) # penalty calculation mr_mode = obj.get_setting('marked_route_mode', 'off') mr_penalty_time = OTime(msec=obj.get_setting('marked_route_penalty_time', 60000)) mr_if_counting_lap = obj.get_setting('marked_route_if_counting_lap', True) mr_if_station_check = obj.get_setting('marked_route_if_station_check', False) mr_station_code = obj.get_setting('marked_route_station_code', 80) if mr_mode == 'off': self.mr_off_radio.setChecked(True) elif mr_mode == 'time': self.mr_time_radio.setChecked(True) else: self.mr_laps_radio.setChecked(True) self.mr_time_edit.setTime(mr_penalty_time.to_time()) self.mr_counting_lap_check.setChecked(mr_if_counting_lap) self.mr_lap_station_check.setChecked(mr_if_station_check) self.mr_lap_station_edit.setValue(mr_station_code) # score settings scores_mode = obj.get_setting('scores_mode', 'off') scores_array = obj.get_setting('scores_array', '40,37,35,33,32,31,30,29,28,27,26,25,24,23,22,21,20,19,18,17,' '16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1') scores_formula = obj.get_setting('scores_formula', '200 - 100 * time / leader') if scores_mode == 'off': self.scores_off.setChecked(True) elif scores_mode == 'array': self.scores_array.setChecked(True) elif scores_mode == 'formula': self.scores_formula.setChecked(True) self.scores_array_edit.setText(scores_array) self.scores_formula_edit.setText(scores_formula) # time settings time_accuracy = obj.get_setting('time_accuracy', 0) time_format_24 = obj.get_setting('time_format_24', 'less24') self.time_settings_accuracy_edit.setValue(time_accuracy) if time_format_24 == 'less24': self.time_settings_format_less.setChecked(True) elif time_format_24 == 'more24': self.time_settings_format_more.setChecked(True) def apply_changes_impl(self): obj = race() start_source = 'protocol' if self.item_start_station.isChecked(): start_source = 'station' elif self.item_start_cp.isChecked(): start_source = 'cp' elif self.item_start_gate.isChecked(): start_source = 'gate' finish_source = 'station' if self.item_finish_cp.isChecked(): finish_source = 'cp' elif self.item_finish_beam.isChecked(): finish_source = 'beam' assign_chip_reading = 'off' if self.chip_reading_unknown.isChecked(): assign_chip_reading = 'only_unknown_members' elif self.chip_reading_always.isChecked(): assign_chip_reading = 'always' start_cp_number = self.item_start_cp_value.value() finish_cp_number = self.item_finish_cp_value.value() old_start_cp_number = obj.get_setting('system_start_cp_number', 31) old_finish_cp_number = obj.get_setting('system_finish_cp_number', 90) if old_start_cp_number != start_cp_number or old_finish_cp_number != finish_cp_number: race().clear_results() obj.set_setting('system_port', self.item_si_port.currentText()) obj.set_setting('system_start_source', start_source) obj.set_setting('system_finish_source', finish_source) obj.set_setting('system_start_cp_number', start_cp_number) obj.set_setting('system_finish_cp_number', finish_cp_number) obj.set_setting('system_assign_chip_reading', assign_chip_reading) obj.set_setting('system_assignment_mode', self.assignment_mode.isChecked()) # result processing rp_mode = 'time' if self.rp_scores_radio.isChecked(): rp_mode = 'scores' rp_score_mode = 'rogain' if self.rp_fixed_scores_radio.isChecked(): rp_score_mode = 'fixed' rp_fixed_scores_value = self.rp_fixed_scores_edit.value() rp_scores_minute_penalty = self.rp_scores_minute_penalty_edit.value() obj.set_setting('result_processing_mode', rp_mode) obj.set_setting('result_processing_score_mode', rp_score_mode) obj.set_setting('result_processing_fixed_score_value', rp_fixed_scores_value) obj.set_setting('result_processing_scores_minute_penalty', rp_scores_minute_penalty) # marked route mr_mode = 'off' if self.mr_laps_radio.isChecked(): mr_mode = 'laps' if self.mr_time_radio.isChecked(): mr_mode = 'time' obj.set_setting('marked_route_mode', mr_mode) mr_penalty_time = time_to_otime(self.mr_time_edit.time()).to_msec() mr_if_counting_lap = self.mr_counting_lap_check.isChecked() mr_if_station_check = self.mr_lap_station_check.isChecked() mr_station_code = self.mr_lap_station_edit.value() obj.set_setting('marked_route_mode', mr_mode) obj.set_setting('marked_route_penalty_time', mr_penalty_time) obj.set_setting('marked_route_if_counting_lap', mr_if_counting_lap) obj.set_setting('marked_route_if_station_check', mr_if_station_check) obj.set_setting('marked_route_station_code', mr_station_code) # score settings scores_mode = 'off' if self.scores_array.isChecked(): scores_mode = 'array' elif self.scores_formula.isChecked(): scores_mode = 'formula' scores_array = self.scores_array_edit.text() scores_formula = self.scores_formula_edit.text() obj.set_setting('scores_mode', scores_mode) obj.set_setting('scores_array', scores_array) obj.set_setting('scores_formula', scores_formula) # time settings time_accuracy = self.time_settings_accuracy_edit.value() time_format_24 = 'less24' if self.time_settings_format_more.isChecked(): time_format_24 = 'more24' obj.set_setting('time_accuracy', time_accuracy) obj.set_setting('time_format_24', time_format_24) ResultCalculation(race()).process_results() GlobalAccess().get_main_window().refresh()
class ResultEditDialog(QDialog): def __init__(self, result, is_new=False): super().__init__(GlobalAccess().get_main_window()) assert (isinstance(result, Result)) self.current_object = result self.is_new = is_new self.time_format = 'hh:mm:ss' time_accuracy = race().get_setting('time_accuracy', 0) if time_accuracy: self.time_format = 'hh:mm:ss.zzz' def exec(self): self.init_ui() self.set_values_from_model() return super().exec() def init_ui(self): self.setWindowTitle(_('Result')) self.setWindowIcon(QIcon(config.ICON)) self.setSizeGripEnabled(False) self.setModal(True) self.layout = QFormLayout(self) self.item_created_at = QTimeEdit() self.item_created_at.setDisplayFormat(self.time_format) self.item_created_at.setReadOnly(True) self.item_card_number = QSpinBox() self.item_card_number.setMaximum(9999999) self.item_bib = QSpinBox() self.item_bib.setMaximum(Limit.BIB) self.item_bib.valueChanged.connect(self.show_person_info) self.label_person_info = QLabel('') self.item_days = QSpinBox() self.item_days.setMaximum(365) self.item_finish = QTimeEdit() self.item_finish.setDisplayFormat(self.time_format) self.item_start = QTimeEdit() self.item_start.setDisplayFormat(self.time_format) self.item_result = QLineEdit() self.item_result.setEnabled(False) self.item_penalty = QTimeEdit() self.item_penalty.setDisplayFormat(self.time_format) self.item_penalty_laps = QSpinBox() self.item_penalty_laps.setMaximum(1000000) self.radio_ok = QRadioButton(_('OK')) self.radio_ok.setChecked(True) self.radio_dns = QRadioButton(_('DNS')) self.radio_dnf = QRadioButton(_('DNF')) self.radio_overtime = QRadioButton(_('Overtime')) self.radio_dsq = QRadioButton(_('DSQ')) self.item_status_comment = AdvComboBox() self.item_status_comment.setMaximumWidth(250) self.item_status_comment.view().setMinimumWidth(650) self.item_status_comment.addItems(StatusComments().get_all()) more24 = race().get_setting('time_format_24', 'less24') == 'more24' self.splits = SplitsText(more24=more24) self.layout.addRow(QLabel(_('Created at')), self.item_created_at) if self.current_object.is_punch(): self.layout.addRow(QLabel(_('Card')), self.item_card_number) self.layout.addRow(QLabel(_('Bib')), self.item_bib) self.layout.addRow(QLabel(''), self.label_person_info) if more24: self.layout.addRow(QLabel(_('Days')), self.item_days) self.layout.addRow(QLabel(_('Start')), self.item_start) self.layout.addRow(QLabel(_('Finish')), self.item_finish) self.layout.addRow(QLabel(_('Penalty')), self.item_penalty) self.layout.addRow(QLabel(_('Penalty legs')), self.item_penalty_laps) self.layout.addRow(QLabel(_('Result')), self.item_result) self.layout.addRow(self.radio_ok) self.layout.addRow(self.radio_dns) self.layout.addRow(self.radio_dnf) self.layout.addRow(self.radio_overtime) self.layout.addRow(self.radio_dsq, self.item_status_comment) if self.current_object.is_punch(): start_source = race().get_setting('system_start_source', 'protocol') finish_source = race().get_setting('system_finish_source', 'station') if start_source == 'protocol' or start_source == 'cp': self.item_start.setDisabled(True) if finish_source == 'cp': self.item_finish.setDisabled(True) self.layout.addRow(self.splits.widget) def cancel_changes(): self.close() def apply_changes(): try: self.apply_changes_impl() except Exception as e: logging.error(str(e)) self.close() button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.button_ok = button_box.button(QDialogButtonBox.Ok) self.button_ok.setText(_('OK')) self.button_ok.clicked.connect(apply_changes) self.button_cancel = button_box.button(QDialogButtonBox.Cancel) self.button_cancel.setText(_('Cancel')) self.button_cancel.clicked.connect(cancel_changes) if self.current_object.person: button_person = button_box.addButton(_('Entry properties'), QDialogButtonBox.ActionRole) button_person.clicked.connect(self.open_person) self.layout.addRow(button_box) self.show() self.item_bib.setFocus() def show_person_info(self): bib = self.item_bib.value() self.label_person_info.setText('') self.button_ok.setEnabled(True) if bib: person = find(race().persons, bib=bib) if person: info = person.full_name if person.group: info = '{}\n{}: {}'.format(info, _('Group'), person.group.name) if person.card_number: info = '{}\n{}: {}'.format(info, _('Card'), person.card_number) self.label_person_info.setText(info) else: self.label_person_info.setText(_('not found')) self.button_ok.setDisabled(True) def set_values_from_model(self): if self.current_object.is_punch(): if self.current_object.card_number: self.item_card_number.setValue( int(self.current_object.card_number)) self.splits.splits(self.current_object.splits) self.splits.show() if self.current_object.created_at: self.item_created_at.setTime( time_to_qtime( datetime.fromtimestamp(self.current_object.created_at))) if self.current_object.finish_time: self.item_finish.setTime( time_to_qtime(self.current_object.finish_time)) if self.current_object.start_time is not None: self.item_start.setTime( time_to_qtime(self.current_object.start_time)) if self.current_object.finish_time: self.item_result.setText(str(self.current_object.get_result())) if self.current_object.penalty_time is not None: self.item_penalty.setTime( time_to_qtime(self.current_object.penalty_time)) if self.current_object.penalty_laps: self.item_penalty_laps.setValue(self.current_object.penalty_laps) if self.current_object.person: self.item_bib.setValue(self.current_object.person.bib) self.item_days.setValue(self.current_object.days) if self.current_object.is_status_ok(): self.radio_ok.setChecked(True) elif self.current_object.status == ResultStatus.DISQUALIFIED: self.radio_dsq.setChecked(True) elif self.current_object.status == ResultStatus.OVERTIME: self.radio_overtime.setChecked(True) elif self.current_object.status == ResultStatus.DID_NOT_FINISH: self.radio_dnf.setChecked(True) elif self.current_object.status == ResultStatus.DID_NOT_START: self.radio_dns.setChecked(True) self.item_status_comment.setCurrentText( self.current_object.status_comment) self.item_bib.selectAll() def open_person(self): try: EntryEditDialog(self.current_object.person).exec() except Exception as e: logging.error(str(e)) def apply_changes_impl(self): result = self.current_object if self.is_new: race().results.insert(0, result) if result.is_punch(): if result.card_number != self.item_card_number.value(): result.card_number = self.item_card_number.value() new_splits = self.splits.splits() if len(result.splits) == len(new_splits): for i, split in enumerate(result.splits): if split != new_splits[i]: break result.splits = new_splits time_ = time_to_otime(self.item_finish.time()) if result.finish_time != time_: result.finish_time = time_ time_ = time_to_otime(self.item_start.time()) if result.start_time != time_: result.start_time = time_ time_ = time_to_otime(self.item_penalty.time()) if result.penalty_time != time_: result.penalty_time = time_ if result.penalty_laps != self.item_penalty_laps.value(): result.penalty_laps = self.item_penalty_laps.value() cur_bib = -1 new_bib = self.item_bib.value() if result.person: cur_bib = result.person.bib if new_bib == 0: if result.person and result.is_punch(): if result.person.card_number == result.card_number: result.person.card_number = 0 result.person = None elif cur_bib != new_bib: new_person = find(race().persons, bib=new_bib) if new_person is not None: assert isinstance(new_person, Person) if result.person: if result.is_punch(): result.person.card_number = 0 result.person = new_person if result.is_punch(): race().person_card_number(result.person, result.card_number) GlobalAccess().get_main_window().get_result_table().model( ).init_cache() if self.item_days.value() != result.days: result.days = self.item_days.value() status = ResultStatus.NONE if self.radio_ok.isChecked(): status = ResultStatus.OK elif self.radio_dsq.isChecked(): status = ResultStatus.DISQUALIFIED elif self.radio_overtime.isChecked(): status = ResultStatus.OVERTIME elif self.radio_dnf.isChecked(): status = ResultStatus.DID_NOT_FINISH elif self.radio_dns.isChecked(): status = ResultStatus.DID_NOT_START if result.status != status: result.status = status status = StatusComments().remove_hint( self.item_status_comment.currentText()) if result.status_comment != status: result.status_comment = status if result.is_punch(): result.clear() try: ResultChecker.checking(result) ResultChecker.calculate_penalty(result) if result.person and result.person.group: GroupSplits(race(), result.person.group).generate(True) except ResultCheckerException as e: logging.error(str(e)) ResultCalculation(race()).process_results() GlobalAccess().get_main_window().refresh() Teamwork().send(result.to_dict())
class EventDetailsDialog(QDialog): def __init__(self, flags, *args, **kwargs): super(EventDetailsDialog, self).__init__(flags=flags, *args) self.setFixedSize(500, 500) self.setWindowFlags(Qt.Dialog) if 'palette' in kwargs: self.setPalette(kwargs.get('palette')) if 'font' in kwargs: self.setFont(kwargs.get('font')) self.setWindowTitle(self.tr('New Event')) self.thread_pool = QThreadPool() self.spinner = WaitingSpinner() self.calendar = kwargs.get('calendar', None) if self.calendar is None: raise RuntimeError('EventDetailsDialog: calendar is not set') self.storage = kwargs.get('storage', Storage(try_to_reconnect=True)) self.storage.try_to_reconnect = True self.title_input = QLineEdit(self) self.description_input = QTextEdit(self) self.date_input = QDateEdit(self) self.time_input = QTimeEdit(self) self.repeat_weekly_input = QCheckBox(self.tr('Repeat weekly'), self) self.event_id = None self.del_btn = None self.is_editing = False self.setup_ui() self.layout().addWidget(self.spinner) def showEvent(self, event): self.move( self.calendar.window().frameGeometry().topLeft() + self.calendar.window().rect().center() - self.rect().center() ) super(EventDetailsDialog, self).showEvent(event) # noinspection PyArgumentList def setup_ui(self): content = QVBoxLayout() content.addWidget(QLabel('{}:'.format(self.tr('Title'))), alignment=Qt.AlignLeft) content.addWidget(self.title_input) content.addWidget(QLabel('{}:'.format(self.tr('Description (optional)'))), alignment=Qt.AlignLeft) content.addWidget(self.description_input) content.addWidget(QLabel('{}:'.format(self.tr('Date'))), alignment=Qt.AlignLeft) content.addWidget(self.date_input) content.addWidget(QLabel('{}:'.format(self.tr('Time'))), alignment=Qt.AlignLeft) content.addWidget(self.time_input) self.repeat_weekly_input.setChecked(False) content.addWidget(self.repeat_weekly_input) buttons = QHBoxLayout() buttons.setAlignment(Qt.AlignRight | Qt.AlignBottom) buttons.addWidget(PushButton(self.tr('Save'), 90, 30, self.save_event_click), 0, Qt.AlignRight) self.del_btn = PushButton(self.tr('Delete'), 90, 30, self.delete_event) buttons.addWidget(self.del_btn) buttons.addWidget(PushButton(self.tr('Cancel'), 90, 30, self.close), 0, Qt.AlignRight) content.addLayout(buttons) self.setLayout(content) def reset_inputs(self, date=None, event_data=None): self.del_btn.setEnabled(False) self.is_editing = False if date is not None: self.event_id = None self.date_input.setDate(QDate(date)) curr_time = (datetime.now() + timedelta(minutes=3)).time().replace(second=0, microsecond=0) self.time_input.setTime(QTime(curr_time)) self.title_input.setText('') self.description_input.setText('') elif event_data is not None: self.event_id = event_data.id self.setWindowTitle(self.tr('Update Event')) self.title_input.setText(event_data.title) self.description_input.setText(event_data.description) self.date_input.setDate(event_data.date) self.time_input.setTime(QTime(event_data.time)) self.repeat_weekly_input.setChecked(event_data.repeat_weekly) self.del_btn.setEnabled(True) self.is_editing = True def validate_inputs(self): if len(self.title_input.text()) < 1: popup.warning(self, '{}!'.format(self.tr('Provide title for the event'))) return False if self.event_id is None: if self.date_input.date().toPyDate() < datetime.now().date(): popup.warning(self, self.tr('Unable to set past event, check date input')) return False if self.time_input.time().toPyTime() < datetime.now().time() and \ self.date_input.date().toPyDate() == datetime.now().date(): popup.warning(self, self.tr('Unable to set past event, check time input')) return False return True def save_event_click(self): if self.validate_inputs(): data = { 'title': self.title_input.text(), 'e_date': self.date_input.date().toPyDate(), 'e_time': self.time_input.time().toPyTime(), 'description': self.description_input.toPlainText(), 'repeat_weekly': self.repeat_weekly_input.isChecked() } err_format = '{}'.format(self.tr('Saving event to database failed')) + ': {}' fn = self.storage.create_event if self.event_id is not None: data['pk'] = self.event_id fn = self.storage.update_event self.exec_worker(fn, self.close_and_update, err_format, **data) def delete_event(self): if popup.question( self, self.tr('Deleting an event'), '{}?'.format(self.tr('Do you really want to delete the event')) ) == QMessageBox.Yes: worker = Worker(self.storage.delete_event, *(self.event_id,)) worker.signals.success.connect(self.close_and_update) worker.err_format = '{}' worker.signals.error.connect(self.popup_error) self.thread_pool.start(worker) def close_and_update(self): self.close() self.calendar.load_events(self.calendar.selectedDate()) self.calendar.update() def exec_worker(self, fn, fn_success, err_format, *args, **kwargs): self.spinner.start() worker = Worker(fn, *args, **kwargs) if fn_success is not None: worker.signals.success.connect(fn_success) worker.err_format = err_format worker.signals.error.connect(self.popup_error) worker.signals.finished.connect(self.spinner.stop) self.thread_pool.start(worker) def popup_error(self, err): popup.error(self, '{}'.format(err[1]))
class EntryEditDialog(QDialog): GROUP_NAME = '' ORGANIZATION_NAME = '' def __init__(self, person, is_new=False): super().__init__(GlobalAccess().get_main_window()) self.is_ok = {} assert (isinstance(person, Person)) self.current_object = person self.is_new = is_new self.time_format = 'hh:mm:ss' time_accuracy = race().get_setting('time_accuracy', 0) if time_accuracy: self.time_format = 'hh:mm:ss.zzz' def exec(self): self.init_ui() self.set_values_from_model() return super().exec() def init_ui(self): self.setWindowTitle(_('Entry properties')) self.setWindowIcon(QIcon(config.ICON)) self.setSizeGripEnabled(False) self.setModal(True) self.layout = QFormLayout(self) self.label_surname = QLabel(_('Last name')) self.item_surname = QLineEdit() self.layout.addRow(self.label_surname, self.item_surname) self.label_name = QLabel(_('First name')) self.item_name = AdvComboBox() self.item_name.addItems(get_names()) self.layout.addRow(self.label_name, self.item_name) self.label_group = QLabel(_('Group')) self.item_group = AdvComboBox() self.item_group.addItems(get_race_groups()) self.layout.addRow(self.label_group, self.item_group) self.label_team = QLabel(_('Team')) self.item_team = AdvComboBox() self.item_team.addItems(get_race_teams()) self.layout.addRow(self.label_team, self.item_team) use_birthday = Config().configuration.get('use_birthday', False) if use_birthday: self.label_birthday = QLabel(_('Birthday')) self.item_birthday = QDateEdit() self.item_birthday.setObjectName('BirthdayDateEdit') self.item_birthday.setDate(date.today()) self.item_birthday.setMaximumDate(date.today()) self.layout.addRow(self.label_birthday, self.item_birthday) else: self.label_year = QLabel(_('Year of birth')) self.item_year = QSpinBox() self.item_year.setObjectName('YearSpinBox') self.item_year.setMinimum(0) self.item_year.setMaximum(date.today().year) self.item_year.editingFinished.connect(self.year_change) self.layout.addRow(self.label_year, self.item_year) self.label_qual = QLabel(_('Qualification')) self.item_qual = AdvComboBox() for i in list(Qualification): self.item_qual.addItem(i.get_title()) self.layout.addRow(self.label_qual, self.item_qual) self.is_ok['bib'] = True self.label_bib = QLabel(_('Bib')) self.item_bib = QSpinBox() self.item_bib.setMinimum(0) self.item_bib.setMaximum(Limit.BIB) self.item_bib.valueChanged.connect(self.check_bib) self.layout.addRow(self.label_bib, self.item_bib) self.label_bib_info = QLabel('') self.layout.addRow(QLabel(''), self.label_bib_info) self.label_start = QLabel(_('Start time')) self.item_start = QTimeEdit() self.item_start.setDisplayFormat(self.time_format) self.layout.addRow(self.label_start, self.item_start) self.label_start_group = QLabel(_('Start group')) self.item_start_group = QSpinBox() self.item_start_group.setMinimum(0) self.item_start_group.setMaximum(99) self.layout.addRow(self.label_start_group, self.item_start_group) self.is_ok['card'] = True self.label_card = QLabel(_('Punch card #')) self.item_card = QSpinBox() self.item_card.setMinimum(0) self.item_card.setMaximum(9999999) self.item_card.valueChanged.connect(self.check_card) self.layout.addRow(self.label_card, self.item_card) self.label_card_info = QLabel('') self.layout.addRow(QLabel(''), self.label_card_info) self.item_rented = QCheckBox(_('rented card')) self.item_paid = QCheckBox(_('is paid')) self.item_out_of_competition = QCheckBox(_('out of competition')) self.item_personal = QCheckBox(_('personal participation')) self.layout.addRow(self.item_rented, self.item_out_of_competition) self.layout.addRow(self.item_paid, self.item_personal) self.label_comment = QLabel(_('Comment')) self.item_comment = QTextEdit() self.item_comment.setTabChangesFocus(True) self.layout.addRow(self.label_comment, self.item_comment) def cancel_changes(): self.close() def apply_changes(): try: self.apply_changes_impl() except Exception as e: logging.error(str(e)) self.close() button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.button_ok = button_box.button(QDialogButtonBox.Ok) self.button_ok.setText(_('OK')) self.button_ok.clicked.connect(apply_changes) self.button_cancel = button_box.button(QDialogButtonBox.Cancel) self.button_cancel.setText(_('Cancel')) self.button_cancel.clicked.connect(cancel_changes) self.layout.addRow(button_box) self.show() def year_change(self): """ Convert 2 digits of year to 4 2 -> 2002 11 - > 2011 33 -> 1933 56 -> 1956 98 - > 1998 0 -> 0 exception! """ widget = self.sender() assert isinstance(widget, QSpinBox) year = widget.value() if 0 < year < 100: cur_year = date.today().year new_year = cur_year - cur_year % 100 + year if new_year > cur_year: new_year -= 100 widget.setValue(new_year) def items_ok(self): ret = True for item_name in self.is_ok.keys(): if self.is_ok[item_name] is not True: ret = False break return ret def check_bib(self): bib = self.item_bib.value() self.label_bib_info.setText('') if bib: person = find(race().persons, bib=bib) if person: if person.bib == self.current_object.bib: self.button_ok.setEnabled(True) return self.button_ok.setDisabled(True) self.is_ok['bib'] = False info = '{}\n{}'.format(_('Number already exists'), person.full_name) if person.group: info = '{}\n{}: {}'.format(info, _('Group'), person.group.name) self.label_bib_info.setText(info) else: self.label_bib_info.setText(_('Number is unique')) self.is_ok['bib'] = True if self.items_ok(): self.button_ok.setEnabled(True) else: self.button_ok.setEnabled(True) def check_card(self): number = self.item_card.value() self.label_card_info.setText('') if number: person = None for _p in race().persons: if _p.card_number and _p.card_number == number: person = _p break if person: if person.card_number == self.current_object.card_number: self.button_ok.setEnabled(True) return self.button_ok.setDisabled(True) self.is_ok['card'] = False info = '{}\n{}'.format(_('Card number already exists'), person.full_name) if person.group: info = '{}\n{}: {}'.format(info, _('Group'), person.group.name) if person.bib: info = '{}\n{}: {}'.format(info, _('Bib'), person.bib) self.label_card_info.setText(info) else: self.label_card_info.setText(_('Card number is unique')) self.is_ok['card'] = True if self.items_ok(): self.button_ok.setEnabled(True) else: self.button_ok.setEnabled(True) def set_values_from_model(self): self.item_surname.setText(self.current_object.surname) self.item_surname.selectAll() self.item_name.setCurrentText(self.current_object.name) if self.current_object.group is not None: self.item_group.setCurrentText(self.current_object.group.name) else: self.item_group.setCurrentText(self.GROUP_NAME) if self.current_object.organization is not None: self.item_team.setCurrentText( self.current_object.organization.name) else: self.item_team.setCurrentText(self.ORGANIZATION_NAME) if self.current_object.qual: self.item_qual.setCurrentText(self.current_object.qual.get_title()) if self.current_object.bib: self.item_bib.setValue(int(self.current_object.bib)) if self.current_object.start_time is not None: time = time_to_qtime(self.current_object.start_time) self.item_start.setTime(time) if self.current_object.start_group is not None: self.item_start_group.setValue(int( self.current_object.start_group)) if self.current_object.card_number: self.item_card.setValue(self.current_object.card_number) self.item_out_of_competition.setChecked( self.current_object.is_out_of_competition) self.item_paid.setChecked(self.current_object.is_paid) self.item_paid.setChecked(self.current_object.is_paid) self.item_personal.setChecked(self.current_object.is_personal) self.item_rented.setChecked(self.current_object.is_rented_card) self.item_comment.setText(self.current_object.comment) use_birthday = Config().configuration.get('use_birthday', False) if use_birthday: if self.current_object.birth_date: self.item_birthday.setDate(self.current_object.birth_date) else: if self.current_object.get_year(): self.item_year.setValue(self.current_object.get_year()) def apply_changes_impl(self): person = self.current_object assert (isinstance(person, Person)) if self.is_new: race().persons.insert(0, person) if person.name != self.item_name.currentText(): person.name = self.item_name.currentText() if person.surname != self.item_surname.text(): person.surname = self.item_surname.text() if (person.group is not None and person.group.name != self.item_group.currentText()) or\ (person.group is None and len(self.item_group.currentText()) > 0): person.group = find(race().groups, name=self.item_group.currentText()) if (person.organization is not None and person.organization.name != self.item_team.currentText()) or \ (person.organization is None and len(self.item_team.currentText()) > 0): organization = find(race().organizations, name=self.item_team.currentText()) if organization is None: organization = Organization() organization.name = self.item_team.currentText() race().organizations.append(organization) Teamwork().send(organization.to_dict()) person.organization = organization if person.qual.get_title() != self.item_qual.currentText(): person.qual = Qualification.get_qual_by_name( self.item_qual.currentText()) if person.bib != self.item_bib.value(): person.bib = self.item_bib.value() new_time = time_to_otime(self.item_start.time()) if person.start_time != new_time: person.start_time = new_time if person.start_group != self.item_start_group.value( ) and self.item_start_group.value(): person.start_group = self.item_start_group.value() if (not person.card_number or int(person.card_number) != self.item_card.value()) \ and self.item_card.value: race().person_card_number(person, self.item_card.value()) if person.is_out_of_competition != self.item_out_of_competition.isChecked( ): person.is_out_of_competition = self.item_out_of_competition.isChecked( ) if person.is_paid != self.item_paid.isChecked(): person.is_paid = self.item_paid.isChecked() if person.is_rented_card != self.item_rented.isChecked(): person.is_rented_card = self.item_rented.isChecked() if person.is_personal != self.item_personal.isChecked(): person.is_personal = self.item_personal.isChecked() if person.comment != self.item_comment.toPlainText(): person.comment = self.item_comment.toPlainText() use_birthday = Config().configuration.get('use_birthday', False) if use_birthday: new_birthday = qdate_to_date(self.item_birthday.date()) if person.birth_date != new_birthday and new_birthday: if person.birth_date or new_birthday != date.today(): person.birth_date = new_birthday else: if person.get_year() != self.item_year.value(): person.set_year(self.item_year.value()) ResultCalculation(race()).process_results() GlobalAccess().get_main_window().refresh() Teamwork().send(person.to_dict())
class CalendarWindow(QMainWindow): def __init__(self, update=False, id=None, timeval=None, taskval=None): super(CalendarWindow, self).__init__() self.setGeometry(300, 300, 400, 400) if update: self.setWindowTitle("Edit Task") else: self.setWindowTitle("Add Task") self.reminder_data = {} self.commons = Commons() self._id = id self._timeval = timeval self._taskval = taskval self.init_ui() self.update = update def init_ui(self): self.init_calendar() self.init_lineedit() self.init_pushbuttons() self.init_timedit() self.show() def init_calendar(self): try: self.date = QDate() self.calendar = QCalendarWidget(self) self.calendar.adjustSize() self.calendar.setMinimumDate(self.date.currentDate()) except Exception as err: print(err) def init_lineedit(self): self.text = QLineEdit(self) self.text.setMaxLength(250) self.text.setGeometry(5, 310, 40, 40) self.text.setFixedWidth(350) if not self.update: self._taskval = "Enter Task Description" self.text.setPlaceholderText(self._taskval) else: self.text.setText(self._taskval) def init_pushbuttons(self): self.OK = QtWidgets.QPushButton(self) self.OK.setText("OK") self.OK.move(195, 360) self.OK.clicked.connect(self.show_main) self.Cancel = QtWidgets.QPushButton(self) self.Cancel.setText("Cancel") self.Cancel.move(295, 360) self.Cancel.clicked.connect(self.close) def init_timedit(self): self.time = QTime() self.tedit = QTimeEdit(self) if not self.update: self._timeval = self.time.currentTime() else: self._timeval = QtCore.QTime.fromString(self._timeval, 'HH:mm:ss') self.tedit.setTime(self._timeval) self.tedit.move(5, 260) def show_main(self): try: selected_date = self.calendar.selectedDate() print(self.calendar.selectedDate()) selected_time = self.tedit.time() print(selected_time.toString()) print(self.text.text()) self.reminder_data['Selected_Date'] = selected_date.toString() self.reminder_data['Selected_Time'] = selected_time.toString() self.reminder_data['Task_Description'] = self.text.text() print("From Calendar: ", self.reminder_data) if self.update: self.commons.prepare_json(self.reminder_data, self._id) else: self.commons.prepare_json(self.reminder_data) self.close() except Exception as err: print(err)
class QFrameSelect(QWidget): frameSelectionChanged = pyqtSignal(int, QTime) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) layout = QVBoxLayout() self.setLayout(layout) self.slider = Slider(self) self.slider.setOrientation(Qt.Horizontal) self.slider.valueChanged.connect(self._handleSliderChange) self.slider.setTickInterval(1) layout.addWidget(self.slider) hlayout = QHBoxLayout() layout.addLayout(hlayout) self.leftLabel = QLabel(self) self.spinBox = QSpinBox(self) self.spinBox.valueChanged.connect(self._handleSpinboxChange) self.currentTime = QTimeEdit(self) self.currentTime.setDisplayFormat("H:mm:ss.zzz") self.currentTime.timeChanged.connect(self._handleTimeEditChange) self.currentTime.editingFinished.connect(self._handleTimeEditFinished) self.rightLabel = QLabel(self) hlayout.addWidget(self.leftLabel) hlayout.addStretch() hlayout.addWidget(QLabel("Frame index:", self)) hlayout.addWidget(self.spinBox) hlayout.addWidget(QLabel("Timestamp:", self)) hlayout.addWidget(self.currentTime) hlayout.addStretch() hlayout.addWidget(self.rightLabel) self.setPtsTimeArray(None) def setValue(self, n): self.slider.setValue(n) def setMinimum(self, n=0): self.slider.setMinimum(n) self.spinBox.setMinimum(n) ms = int(self.pts_time[n] * 1000 + 0.5) s, ms = divmod(ms, 1000) m, s = divmod(s, 60) h, m = divmod(m, 60) self.currentTime.setMinimumTime(QTime(h, m, s, ms)) self.leftLabel.setText(f"{n} ({h}:{m:02d}:{s:02d}.{ms:03d})") def setMaximum(self, n=None): if n is None: n = len(self.pts_time) - 1 self.slider.setMaximum(n) self.spinBox.setMaximum(n) ms = int(self.pts_time[n] * 1000 + 0.5) s, ms = divmod(ms, 1000) m, s = divmod(s, 60) h, m = divmod(m, 60) self.currentTime.setMaximumTime(QTime(h, m, s, ms)) self.rightLabel.setText(f"{n} ({h}:{m:02d}:{s:02d}.{ms:03d})") def setStartEndVisible(self, value): self.leftLabel.setHidden(not bool(value)) self.rightLabel.setHidden(not bool(value)) def setPtsTimeArray(self, pts_time=None): self.pts_time = pts_time if pts_time is not None: N = len(pts_time) self.setMinimum(0) self.setMaximum(N - 1) self.slider.setValue(0) self.slider.setSnapValues(None) self.slider.setDisabled(False) self.spinBox.setDisabled(False) self.currentTime.setDisabled(False) else: self.slider.setMinimum(0) self.slider.setMaximum(0) self.slider.setSnapValues(None) self.slider.setDisabled(True) self.spinBox.setDisabled(True) self.currentTime.setDisabled(True) def _handleSliderChange(self, n): self.spinBox.blockSignals(True) self.spinBox.setValue(n) self.spinBox.blockSignals(False) pts_time = self.pts_time[n] ms = int(pts_time * 1000 + 0.5) s, ms = divmod(ms, 1000) m, s = divmod(s, 60) h, m = divmod(m, 60) self.currentTime.blockSignals(True) self.currentTime.setTime(QTime(h, m, s, ms)) self.currentTime.blockSignals(False) self.frameSelectionChanged.emit(n, QTime(h, m, s, ms)) def _handleSpinboxChange(self, n): self.slider.blockSignals(True) self.slider.setValue(n) self.slider.blockSignals(False) pts_time = self.pts_time[n] ms = int(pts_time * 1000 + 0.5) s, ms = divmod(ms, 1000) m, s = divmod(s, 60) h, m = divmod(m, 60) self.currentTime.blockSignals(True) self.currentTime.setTime(QTime(h, m, s, ms)) self.currentTime.blockSignals(False) self.frameSelectionChanged.emit(n, QTime(h, m, s, ms)) def _handleTimeEditChange(self, t): pts = t.msecsSinceStartOfDay() / 1000 try: n = search(self.pts_time, pts + 0.0005, dir="-") except IndexError: n = 0 if n != self.slider.value(): self.slider.blockSignals(True) self.slider.setValue(n) self.slider.blockSignals(False) self.spinBox.blockSignals(True) self.spinBox.setValue(n) self.spinBox.blockSignals(False) pts_time = self.pts_time[n] ms = int(pts_time * 1000 + 0.5) s, ms = divmod(ms, 1000) m, s = divmod(s, 60) h, m = divmod(m, 60) self.frameSelectionChanged.emit(n, QTime(h, m, s, ms)) def _handleTimeEditFinished(self): t = self.currentTime.time() pts = t.msecsSinceStartOfDay() / 1000 n = search(self.pts_time, pts + 0.0005, dir="-") pts_time = self.pts_time[n] ms = int(pts_time * 1000 + 0.5) s, ms = divmod(ms, 1000) m, s = divmod(s, 60) h, m = divmod(m, 60) T = QTime(h, m, s, ms) if t != T: self.currentTime.setTime(T)
class TimeSynchronizer(QDialog): """Time synchronization widget. Make this widget look all big and important, but really, it's just an indirect way of getting a reference clock time (the more straightforward way being to just enter one in the text input). However, this widget comes in most useful when synchronizing the reference clock with race officials. When they press start, we press start/hit enter on this widget. We then use that moment in time as our reference clock time. """ TIME_POINT_SIZE = 24 BUTTON_POINT_SIZE = 54 def __init__(self, parent=None): """Initialize the TimeSynchronizer instance.""" super().__init__(parent=parent) self.instruction_label = QLabel('Adjust desired synchronization time and press ' '"Sync" button to set reference clock time.') self.instruction_label.setWordWrap(True) self.time_timeedit = QTimeEdit() self.time_timeedit.setDisplayFormat(defaults.DATETIME_FORMAT) font = self.time_timeedit.font() font.setPointSize(self.TIME_POINT_SIZE) self.time_timeedit.setFont(font) self.sync_button = QPushButton('Sync') font = self.sync_button.font() font.setPointSize(self.BUTTON_POINT_SIZE) self.sync_button.setFont(font) self.setLayout(QVBoxLayout()) self.layout().addWidget(self.instruction_label) self.layout().addWidget(self.time_timeedit) self.layout().addWidget(self.sync_button) self.sync_button.clicked.connect(self.handle_clicked) def show(self): """Show the TimeSynchronizer. Initialize the time to zero. """ self.read_settings() self.time_timeedit.setTime(QTime(0, 0)) super().show() def hide(self): """Save geometry settings.""" super().hide() self.write_settings() def handle_clicked(self): """Handler for sync button click.""" reference_time = self.time_timeedit.time() current_time = QTime.currentTime() reference_clock_time = current_time.addMSecs(-reference_time.msecsSinceStartOfDay()) self.clicked.emit(reference_clock_time) def read_settings(self): """Read settings.""" group_name = self.__class__.__name__ settings = QSettings() settings.beginGroup(group_name) if settings.contains('pos'): self.move(settings.value('pos')) settings.endGroup() def write_settings(self): """Write settings.""" group_name = self.__class__.__name__ settings = QSettings() settings.beginGroup(group_name) settings.setValue('pos', self.pos()) settings.endGroup() clicked = pyqtSignal(QTime)
class IPFDSNWidget(QWidget): sigTracesReplaced = pyqtSignal(obspy.core.stream.Stream, obspy.core.inventory.inventory.Inventory) sigTracesAppended = pyqtSignal(obspy.core.stream.Stream, obspy.core.inventory.inventory.Inventory) stream = None inventory = None def __init__(self, parent=None): super().__init__() self.parent = parent # this is for managing the event populated form elements # self.eventInfoPopulated = False # self.currentEvent = None self.__buildUI__() self.show() def __buildUI__(self): # Put together the options container gridLayout = QGridLayout() optionsContainer = QWidget() optionsContainer.setLayout(gridLayout) # First lets populate the client drop down self.cb = QComboBox() label_service_name = QLabel(self.tr('Service:')) fdsn_dictionary = URL_MAPPINGS fdsn_dictionary.update( {'RaspShake': 'https://fdsnws.rasberryshakedata.com'}) for key in sorted(URL_MAPPINGS.keys()): self.cb.addItem(key) self.cb.setCurrentText('IRIS') self.cb.currentIndexChanged[str].connect(self.onActivated_cb) validator = IPValidator(self) label_network_name = QLabel(self.tr('Network: ')) self.networkNameBox = QLineEdit() self.networkNameBox.setToolTip( 'Wildcards OK \nCan be SEED network codes or data center defined codes. \nMultiple codes are comma-separated (e.g. "IU,TA").' ) self.networkNameBox.setValidator(validator) label_station_name = QLabel(self.tr('Station: ')) self.stationNameBox = QLineEdit() self.stationNameBox.setToolTip( 'Wildcards OK \nOne or more SEED station codes. \nMultiple codes are comma-separated (e.g. "ANMO,PFO")' ) self.stationNameBox.setValidator(validator) label_location_str = QLabel(self.tr('Location:')) self.location_Box = QLineEdit('*') self.location_Box.setToolTip( 'Wildcards OK \nOne or more SEED location identifiers. \nMultiple identifiers are comma-separated (e.g. "00,01"). \nAs a special case “--“ (two dashes) will be translated to a string of two space characters to match blank location IDs.' ) self.location_Box.setValidator(validator) label_channel_str = QLabel(self.tr('Channel:')) self.channel_Box = QLineEdit('*') self.channel_Box.setToolTip( 'Wildcards OK \nOne or more SEED channel codes. \nMultiple codes are comma-separated (e.g. "BHZ,HHZ")' ) self.channel_Box.setValidator(validator) label_startDate = QLabel(self.tr('Start Date (UTC):')) self.startDate_edit = QDateEdit() self.startDate_edit.setMinimumDate(QDate(1900, 1, 1)) self.startDate_edit.setDisplayFormat('yyyy-MM-dd') self.startDate_edit.setDate(self.startDate_edit.minimumDate()) label_startTime = QLabel(self.tr('Start Time (UTC):')) self.startTime_edit = QTimeEdit() self.startTime_edit.setDisplayFormat('HH:mm:ss.zzz') label_traceLength = QLabel(self.tr('Trace Length (s)')) self.traceLength_t = QSpinBox() self.traceLength_t.setMinimum(1) self.traceLength_t.setMaximum(999999999) self.traceLength_t.setValue(3600) replaceWaveButton = QPushButton('Replace') replaceWaveButton.clicked.connect(self.onClicked_replace) appendWaveButton = QPushButton('Append') appendWaveButton.clicked.connect(self.onClicked_append) self.stationListWidget = QListWidget() self.stationListWidget.setSelectionMode( QAbstractItemView.ExtendedSelection) self.stationListWidget.itemSelectionChanged.connect( self.populateStationInfoFromStationList) self.browserButton = QPushButton('Station Browser') self.browserButton.clicked.connect(self.onClicked_browserButton) gridLayout.addWidget(label_service_name, 0, 0) gridLayout.addWidget(self.cb, 0, 1) gridLayout.addWidget(label_network_name, 1, 0) gridLayout.addWidget(self.networkNameBox, 1, 1) gridLayout.addWidget(label_station_name, 2, 0) gridLayout.addWidget(self.stationNameBox, 2, 1) gridLayout.addWidget(label_location_str, 3, 0) gridLayout.addWidget(self.location_Box, 3, 1) gridLayout.addWidget(label_channel_str, 4, 0) gridLayout.addWidget(self.channel_Box, 4, 1) gridLayout.addWidget(label_startDate, 5, 0) gridLayout.addWidget(self.startDate_edit, 5, 1) gridLayout.addWidget(label_startTime, 6, 0) gridLayout.addWidget(self.startTime_edit, 6, 1) gridLayout.addWidget(label_traceLength, 7, 0) gridLayout.addWidget(self.traceLength_t, 7, 1) # gridLayout.addWidget(importEventButton, 8, 1, 1, 2) horzLayout = QHBoxLayout(self) horzLayout.addWidget(replaceWaveButton) horzLayout.addWidget(appendWaveButton) addGroupBox = QGroupBox("Get Waveform(s)") addGroupBox.setLayout(horzLayout) vertlayout = QVBoxLayout(self) vertlayout.addWidget(optionsContainer) vertlayout.addWidget(addGroupBox) vertlayout.addWidget(self.stationListWidget) vertlayout.addWidget(self.browserButton) self.setLayout(vertlayout) # create stationdialog here so that you only create it once, from here on you just run exec_() to make it pop up self.stationDialog = IPStationBrowser.IPStationDialog() def onClicked_browserButton(self): if self.stationDialog.exec_(self.startDate_edit.date(), network=self.networkNameBox.text(), station=self.stationNameBox.text(), location=self.location_Box.text(), channel=self.channel_Box.text()): self.inventory = self.stationDialog.getInventory() inv_contents = self.inventory.get_contents() stationList = [] # fill up the stationList with stations for item in inv_contents['stations']: stationList.append(item.strip()) self.stationListWidget.clear() self.stationListWidget.addItems(stationList) if self.stationDialog.getStartDate() is not None: self.startDate_edit.setDate(self.stationDialog.getStartDate()) # def populateWithEventInfo(self): # if self.parent.eventWidget.hasValidEvent(): # self.currentEvent = self.parent.eventWidget.Dict() # else: # msgBox = QMessageBox() # msgBox.setIcon(QMessageBox.Warning) # msgBox.setText('There is not a valid event in the Event Tab') # msgBox.setWindowTitle("Oops...") # msgBox.exec_() # return # if self.currentEvent is not None: # date = self.currentEvent['UTC Date'] # time = self.currentEvent['UTC Time'][0:5] # qdate = QDate.fromString(date, 'yyyy-MM-dd') # qtime = QTime.fromString(time, 'HH:mm') # qtime.addSecs(-5*60) # start about 5 minutes before event # self.startDate_edit.setDate(qdate) # self.startTime_edit.setTime(qtime) # self.eventInfoPopulated = True # # if someone edits the event info, reflect the changes here # @QtCore.pyqtSlot(dict) # def updateEventInfo(self, event): # if not self.eventInfoPopulated: # return # if self.parent.eventWidget.hasValidEvent(): # self.currentEvent = event # if self.currentEvent is not None: # date = event['UTC Date'] # time = event['UTC Time'][0:5] # qdate = QDate.fromString(date, 'yyyy-MM-dd') # qtime = QTime.fromString(time, 'HH:mm') # qtime.addSecs(-5*60) # start about 5 minutes before event # self.startDate_edit.setDate(qdate) # self.startTime_edit.setTime(qtime) def populateStationInfoFromStationList(self): items = self.stationListWidget.selectedItems() if len(items) < 1: return # nothing to do netList = [] staList = [] for item in items: text = item.text() text = text.split(' ')[0] netSta = text.split('.') netList.append(netSta[0]) staList.append(netSta[1]) netList = list(set(netList)) staList = list(set(staList)) netString = '' for net in netList: netString = netString + net + ', ' staString = '' for sta in staList: staString = staString + sta + ', ' self.networkNameBox.setText(netString[:-2]) self.stationNameBox.setText(staString[:-2]) def onActivated_cb(self, key): if (key != 'choose...'): url = URL_MAPPINGS[key] def onClicked_replace(self): self.downloadWaveforms() if self.stream is not None and self.inventory is not None: self.sigTracesReplaced.emit(self.stream, self.inventory) def onClicked_append(self): self.downloadWaveforms() if self.stream is not None and self.inventory is not None: self.sigTracesAppended.emit(self.stream, self.inventory) # get waveform button was clicked def downloadWaveforms(self): # first check to make sure the boxes are filled...addWidget # TODO!!! # get the inputs...inputs service = self.cb.currentText() if (service == 'choose...'): msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText('Please select a service to search') msg.setWindowTitle('oops...') msg.setStandardButtons(QMessageBox.Ok) msg.exec_() return # Clear old streams because we don't need them anymore self.clearWaveforms() network = self.networkNameBox.text().upper().replace(' ', '') self.networkNameBox.setText(network) station = self.stationNameBox.text().upper().replace(' ', '') self.stationNameBox.setText(station) location = self.location_Box.text().upper().replace(' ', '') self.location_Box.setText(location) channel = self.channel_Box.text().upper().replace(' ', '') self.channel_Box.setText(channel) date = self.startDate_edit.date().toPyDate() time = self.startTime_edit.time().toPyTime() traceLength = self.traceLength_t.value() utcString = str(date) + 'T' + str(time) startTime = UTCDateTime(utcString) endTime = startTime + traceLength # Check for unfilled boxes if (network == '' or station == '' or channel == ''): msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText('You are missing some important info...') msg.setWindowTitle('oops...') msg.setDetailedText( "Network, Station, Location, and Channel are all required data." ) msg.setStandardButtons(QMessageBox.Ok) msg.exec_() return # Download the waveforms # self.parent.setStatus('connecting to '+service) client = Client(service) # self.parent.setStatus('downloading Waveforms...') try: self.stream = client.get_waveforms(network, station, location, channel, startTime, endTime) except Exception: # self.parent.setStatus('') msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText('Failure loading waveform') msg.setWindowTitle('oops...') msg.setDetailedText( "Double check that the values you entered are valid and the time and date are appropriate." ) msg.setStandardButtons(QMessageBox.Ok) msg.exec_() return for trace in self.stream: trace.data = trace.data - np.mean(trace.data) self.stream.merge(fill_value=0) # self.parent.setStatus('downloading Inventory...') # self.parent.consoleBox.append( 'Downloaded waveforms from '+service ) # Now get the corresponding stations try: self.inventory = client.get_stations(network=network, station=station) except: # self.parent.setStatus('') msg = QMessageBox() msg.setIcon(QMessageBox.Warning) msg.setText('Failure loading Inventory') msg.setWindowTitle('oops...') msg.setDetailedText( "Double check that the values you entered are valid and the time and date are appropriate." ) msg.setStandardButtons(QMessageBox.Ok) msg.exec_() return # self.parent.consoleBox.append( 'Downloaded stations from '+service) # self.parent.setStatus('Finished...', 3000) def getStreams(self): return self.stream def getInventory(self): return self.inventory def getService(self): return self.cb.currentText() def clearWaveforms(self): self.stream = None self.inventory = None def clear(self): self.clearWaveforms() self.stationListWidget.clear() self.cb.setCurrentText( 'IRIS') # default to IRIS because why the hell not? self.networkNameBox.clear() self.stationNameBox.clear() self.location_Box.setText('*') self.channel_Box.setText('*') self.startDate_edit.setDate(self.startDate_edit.minimumDate()) self.startTime_edit.setTime(self.startTime_edit.minimumTime()) self.traceLength_t.setValue(3600)
class AlarmWidget(QWidget): def __init__(self): super().__init__() self.initUI() # Флаг, чтобы функция вызова будильника не вызвыалась с каждым тиком self.flag_get_up = True # Нулевое время для сброса часов self.zero_time = QTime(0, 0) # Пустая ссылка self.url = QUrl() # Инициализируем плеер и плейлист, который после зацикливаем self.playlist = QMediaPlaylist(self) self.playlist.setPlaybackMode(QMediaPlaylist.Loop) self.player = QMediaPlayer() # Кнопка для выбора файла с музыкой self.btn_getfile = QPushButton('Выбрать файл', self) self.btn_getfile.setFont(QFont('Times', 10)) self.btn_getfile.move(142.5, 25) self.btn_getfile.resize(215, 50) self.btn_getfile.setVisible(False) self.btn_getfile.clicked.connect(self.getfile) # Радио-кнопка для включения будильника self.radio_btn1 = QRadioButton('вкл', self) self.radio_btn1.move(0, 15) self.radio_btn1.setFont(QFont('Times', 10)) self.radio_btn1.toggled.connect(self.on_off) # Радио-кнопка для выключения будильника self.radio_btn2 = QRadioButton('выкл', self) self.radio_btn2.move(0, 40) self.radio_btn2.setChecked(True) self.radio_btn2.setFont(QFont('Times', 10)) self.radio_btn2.toggled.connect(self.on_off) # Значение будильника self.timer_edit = QTimeEdit(self) self.timer_edit.setDisplayFormat('hh:mm') self.timer_edit.move(200, 110) self.timer_edit.resize(100, 50) self.timer_edit.setFont(QFont('Times', 18, QFont.Bold)) self.timer_edit.setVisible(False) # Бирка self.lbl = QLabel('Будильник:', self) self.lbl.move(0, 0) self.lbl.setFont(QFont('Times', 10)) # Подсказка для кнопки выбора мелодии self.lbl2 = QLabel('Выберите мелодию для будильника:', self) self.lbl2.move(142.5, 0) self.lbl2.setVisible(False) self.lbl2.setFont(QFont('Times', 10)) # Бирка self.lbl3 = QLabel('Будильник установлен на:', self) self.lbl3.move(175, 185) self.lbl3.setFont(QFont('Times', 10)) self.lbl3.setVisible(False) # Бирка self.lbl4 = QLabel('Установите время будильника:', self) self.lbl4.move(150, 85) self.lbl4.setFont(QFont('Times', 10)) self.lbl4.setVisible(False) # Кнопка выключения будильника, когда он сработает self.btn = QPushButton('Выключить\nбудильник', self) self.btn.clicked.connect(self.awake) self.btn.resize(100, 100) self.btn.move(200, 200) self.btn.setFont(QFont('Times', 11, QFont.ExtraBold)) self.btn.setVisible(False) # Дисплей для вывода значения будильника self.dis2 = QLCDNumber(self) self.dis2.move(200, 210) self.dis2.resize(100, 50) self.dis2.setVisible(False) # Дисплей с текущим временем self.dis1 = QLCDNumber(self) self.dis1.move(375, 25) self.dis1.resize(100, 50) # Бирка self.lbl5 = QLabel('Сейчас:', self) self.lbl5.move(375, 0) self.lbl5.setFont(QFont('Times', 10)) # Таймер self.nTimer = QTimer() self.nTimer.timeout.connect(self.repeatTime) self.nTimer.start() def initUI(self): self.setGeometry(100, 100, 500, 500) self.setWindowTitle('Будильник') def repeatTime(self): # Вытаскиваем системное время и преобразуем в строку self.time = QTime().currentTime() time_text = self.time.toString('hh:mm') # Вытаскиваем выставленное значение будильника и преобразуем в строку timer = self.timer_edit.time() timer_text = timer.toString('hh:mm') # Выводим значения будильника на дисплей self.dis2.display(timer_text) # Выводим текущее время self.dis1.display(time_text) # Проверяем условия срабатывания будильника if timer_text == time_text and self.flag_get_up and self.radio_btn1.isChecked( ): self.flag_get_up = False self.get_up() else: self.flag_get_up = True def awake(self): # Устанавливаем нулевое значение времени будильника self.timer_edit.setTime(self.zero_time) # Махинация с показом виджетов self.lbl.setVisible(True) self.lbl2.setVisible(True) self.lbl3.setVisible(True) self.lbl4.setVisible(True) self.radio_btn1.setVisible(True) self.radio_btn2.setVisible(True) self.btn_getfile.setVisible(True) self.dis2.setVisible(True) self.timer_edit.setVisible(True) self.btn.setVisible(False) # Останавливаем музыку self.player.stop() def get_up(self): # Махинации с показом виджетов self.lbl.setVisible(False) self.lbl2.setVisible(False) self.lbl3.setVisible(False) self.lbl4.setVisible(False) self.radio_btn1.setVisible(False) self.radio_btn2.setVisible(False) self.btn_getfile.setVisible(False) self.dis2.setVisible(False) self.timer_edit.setVisible(False) self.btn.setVisible(True) # Включаем музыку self.player.play() def getfile(self): # Достаем файл с мелодией и сохраняем её путь fname = QFileDialog.getOpenFileName(self, 'Open File', '/home', 'Audio Files (*mp3 *wav)') self.url = QUrl.fromLocalFile(fname[0]) # Устанавливаем музыку в плеер self.content = QMediaContent(self.url) self.playlist.clear() self.playlist.addMedia(self.content) self.player.setPlaylist(self.playlist) def on_off(self): # Включаем/выключаем будильник if self.radio_btn1.isChecked(): self.btn_getfile.setVisible(True) self.timer_edit.setVisible(True) self.dis2.setVisible(True) self.lbl2.setVisible(True) self.lbl3.setVisible(True) self.lbl4.setVisible(True) else: self.btn_getfile.setVisible(False) self.timer_edit.setVisible(False) self.dis2.setVisible(False) self.lbl2.setVisible(False) self.lbl3.setVisible(False) self.lbl4.setVisible(False) self.timer_edit.setTime(self.zero_time) self.btn.setVisible(False) self.player.stop()
class MainWidget(QWidget): def __init__(self): QWidget.__init__(self) # Set Time One Group self.time_one_calendar = QCalendarWidget() self.time_one_country_combobox = QComboBox() self.time_one_vbox = QVBoxLayout() self.time_one_groupbox = QGroupBox("Time One") self.time_one_bottom_hbox = QHBoxLayout() self.time_one_time_edit = QTimeEdit() self.time_one_default_button = QPushButton() self.time_one_default_button.setIcon(QIcon("%s/gnome-set-time.png" % icon_path)) self.time_one_default_button.setMaximumSize(50, 50) self.time_one_bottom_hbox.addWidget(self.time_one_time_edit) self.time_one_bottom_hbox.addWidget(self.time_one_default_button) self.time_one_vbox.addWidget(self.time_one_country_combobox) self.time_one_vbox.addWidget(self.time_one_calendar) self.time_one_vbox.addLayout(self.time_one_bottom_hbox) self.time_one_groupbox.setLayout(self.time_one_vbox) # Set Time Two Group self.time_two_groupbox = QGroupBox("Time Two") self.time_two_calendar = QCalendarWidget() self.time_two_vbox = QVBoxLayout() self.time_two_country_combobox = QComboBox() self.time_two_bottom_hbox = QHBoxLayout() self.time_two_time_edit = QTimeEdit() self.time_two_default_button = QPushButton() self.time_two_default_button.setIcon(QIcon("%s/gnome-set-time.png" % icon_path)) self.time_two_default_button.setMaximumSize(50, 50) self.time_two_bottom_hbox.addWidget(self.time_two_time_edit) self.time_two_bottom_hbox.addWidget(self.time_two_default_button) self.time_two_vbox.addWidget(self.time_two_country_combobox) self.time_two_vbox.addWidget(self.time_two_calendar) self.time_two_vbox.addLayout(self.time_two_bottom_hbox) self.time_two_groupbox.setLayout(self.time_two_vbox) # Set main layout self.main_layout = QHBoxLayout() self.main_layout.addWidget(self.time_one_groupbox) self.main_layout.addWidget(self.time_two_groupbox) self.setLayout(self.main_layout) # Wire-up your widgets! self.time_one_connect() self.time_two_connect() self.time_one_default_button.clicked.connect(self.set_local_time_one) self.time_two_default_button.clicked.connect(self.set_local_time_two) # Set the local time for time one self.set_local_country() self.set_local_time_one() # Finally, convert the second time based on the first self.convert_timeone_to_timetwo() def set_local_country(self): global_timezone_list = timezone_info.get_global_timezone_list() local_tz_index = global_timezone_list.index(str(self.get_local_timezone())) self.time_one_country_combobox.addItems(global_timezone_list) self.time_one_country_combobox.setCurrentIndex(local_tz_index) self.time_two_country_combobox.addItems(global_timezone_list) # To-do: Current solution works for Debian systems. Need to find repo solution that # allows for something like "from tzlocal import get_localzone" @staticmethod def get_local_timezone(): timezone_file = '/etc/timezone' try: file = open(timezone_file, 'r') system_timezone = file.read().rstrip() except IOError: print("Unable to open %s") & timezone_file system_timezone = 'UTC' return system_timezone @staticmethod def get_local_times(): local_hour = datetime.datetime.now().strftime("%H") local_minute = datetime.datetime.now().strftime("%M") local_current_time = QTime(int(local_hour), int(local_minute), 0, 0) return local_current_time def set_local_time_one(self): # Set time for one time local_current_time = self.get_local_times() self.time_one_time_edit.setTime(local_current_time) # Set date for one calendar self.time_one_calendar.setSelectedDate(QDate.currentDate()) # Convert the second time based on the first self.convert_timeone_to_timetwo() def set_local_time_two(self): # Set time for one time local_current_time = self.get_local_times() self.time_two_time_edit.setTime(local_current_time) # Set date for one calendar self.time_two_calendar.setSelectedDate(QDate.currentDate()) # Convert the first time based on the second self.convert_timetwo_to_timeone() def time_one_connect(self): self.time_one_country_combobox.activated.connect(self.convert_timeone_to_timetwo) self.time_one_calendar.clicked.connect(self.convert_timeone_to_timetwo) self.time_one_calendar.currentPageChanged.connect(self.convert_timeone_to_timetwo) self.time_one_time_edit.timeChanged.connect(self.convert_timeone_to_timetwo) def time_two_connect(self): self.time_two_country_combobox.activated.connect(self.convert_timeone_to_timetwo) self.time_two_calendar.clicked.connect(self.convert_timetwo_to_timeone) self.time_two_calendar.currentPageChanged.connect(self.convert_timetwo_to_timeone) self.time_two_time_edit.timeChanged.connect(self.convert_timetwo_to_timeone) def time_one_disconnect(self): self.time_one_calendar.clicked.disconnect() self.time_one_country_combobox.activated.disconnect() self.time_one_time_edit.timeChanged.disconnect() def time_two_disconnect(self): self.time_two_calendar.clicked.disconnect() self.time_two_country_combobox.activated.disconnect() self.time_two_time_edit.timeChanged.disconnect() def clear_combo_boxes(self): self.time_one_country_combobox.clear() self.time_two_country_combobox.clear() def __amend_country_region(self): """ Used to add the regional header before converting if a region outside of global is used. """ current_region = timezone_info.get_city_region(self.time_one_country_combobox.currentText()) time_one_country = self.time_one_country_combobox.currentText() time_two_country = self.time_two_country_combobox.currentText() if '/' not in time_one_country: time_one_country = current_region+'/'+self.time_one_country_combobox.currentText() time_two_country = current_region+'/'+self.time_two_country_combobox.currentText() return time_one_country, time_two_country def convert_timeone_to_timetwo(self): # Disconnect time two widgets,so that they do not run self.time_two_disconnect() time_one_country, time_two_country = self.__amend_country_region() date_time_one = datetime.datetime(self.time_one_calendar.yearShown(), self.time_one_calendar.monthShown(), self.time_one_calendar.selectedDate().day(), self.time_one_time_edit.time().hour(), self.time_one_time_edit.time().minute()) first_tz = timezone(time_one_country) second_tz = timezone(time_two_country) first_dt = first_tz.localize(date_time_one) second_dt = first_dt.astimezone(second_tz) new_date_two = QDate(second_dt.year, second_dt.month, second_dt.day) self.time_two_calendar.setSelectedDate(new_date_two) new_time_two = QTime(int(second_dt.hour), int(second_dt.minute)) self.time_two_time_edit.setTime(new_time_two) # Reconnect time one widgets. self.time_two_connect() def convert_timetwo_to_timeone(self): # Disconnect time one widgets,so that they do not run self.time_one_disconnect() time_one_country, time_two_country = self.__amend_country_region() date_time_two = datetime.datetime(self.time_two_calendar.yearShown(), self.time_two_calendar.monthShown(), self.time_two_calendar.selectedDate().day(), self.time_two_time_edit.time().hour(), self.time_two_time_edit.time().minute()) first_tz = timezone(time_one_country) second_tz = timezone(time_two_country) second_dt = second_tz.localize(date_time_two) first_dt = second_dt.astimezone(first_tz) new_date_one = QDate(first_dt.year, first_dt.month, first_dt.day) self.time_one_calendar.setSelectedDate(new_date_one) new_time_one = QTime(int(first_dt.hour), int(first_dt.minute)) self.time_one_time_edit.setTime(new_time_one) # Reconnect time one widgets self.time_one_connect()
class VideoWindow(QWidget): def __init__(self, vidPath): super().__init__() self.fullPath = vidPath self.startTime = 0 self.endTime = 0 self.init_ui() def init_ui(self): layout = QVBoxLayout() self.setLayout(layout) self.setWindowTitle(self.fullPath) self.mediaPlayer = QMediaPlayer(None, QMediaPlayer.VideoSurface) self.videoWidget = QVideoWidget() self.playButton = QPushButton() self.playButton.setEnabled(True) self.playButton.setIcon(self.style().standardIcon(QStyle.SP_MediaPlay)) self.playButton.setFixedWidth(100) self.playButton.setFixedHeight(50) self.playButton.clicked.connect(self.play) self.trimButton = QPushButton("Trim") self.trimButton.setFixedWidth(150) self.trimButton.setFixedHeight(50) self.trimButton.clicked.connect(self.trimVid) self.positionSlider = QSlider(QtCore.Qt.Horizontal) self.positionSlider.setRange(0, 0) self.positionSlider.sliderMoved.connect(self.setPosition) self.rangeSlider = qrangeslider.QRangeSlider() self.rangeSlider.setRange(0, 0) self.rangeSlider.endValueChanged.connect(self.adjustForEnd) self.rangeSlider.startValueChanged.connect(self.adjustForStart) self.rangeSlider.setFixedHeight(15) self.startTimeInput = QTimeEdit() self.endTimeInput = QTimeEdit() self.startTimeInput.setDisplayFormat('hh:mm:ss.zzz') self.endTimeInput.setDisplayFormat('hh:mm:ss.zzz') self.startTimeInput.timeChanged.connect(self.startInputChanged) self.endTimeInput.timeChanged.connect(self.endInputChanged) self.mediaPlayer.setMedia( QMediaContent(QtCore.QUrl.fromLocalFile(self.fullPath))) layout.addWidget(self.videoWidget) self.mediaPlayer.setVideoOutput(self.videoWidget) self.mediaPlayer.setNotifyInterval(10) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.durationChanged.connect(self.durationChanged) controlLayout = QVBoxLayout() controlLayout.setContentsMargins(0, 0, 0, 0) controlLayout.addWidget(self.rangeSlider) controlLayout.addWidget(self.positionSlider) timeInputLayout = QHBoxLayout() timeInputLayout.addWidget(self.playButton) timeInputLayout.addWidget(self.startTimeInput) timeInputLayout.addWidget(self.endTimeInput) timeInputLayout.addWidget(self.trimButton) controlLayout.addLayout(timeInputLayout) layout.addLayout(controlLayout) self.mediaPlayer.play() self.resize(1024, 700) self.show() def closeEvent(self, event): self.mediaPlayer.stop() self.videoWidget.setParent(None) self.mediaPlayer.setParent(None) self.mediaPlayer.deleteLater() self.videoWidget.deleteLater() def trimVid(self): self.trimButton.setEnabled(False) outName = mytools.getAvailableName(self.fullPath, 'Trim') print(outName) trimStartTime = self.startTimeInput.time().toString('hh:mm:ss.zzz') trimEndTime = self.endTimeInput.time().toString('hh:mm:ss.zzz') try: ff = FFmpeg(inputs={self.fullPath: None}, outputs={ outName: [ '-ss', trimStartTime, '-to', trimEndTime, '-c:v', 'copy', '-c:a', 'copy', ] }) ff.run() except Exception as e: msg = QMessageBox() msg.setWindowTitle("Trim Failed") msg.setText(str(e)) msg.setIcon(QMessageBox.Critical) showMsg = msg.exec_() self.trimButton.setEnabled(True) def play(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def mediaStateChanged(self, state): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPause)) else: self.playButton.setIcon(self.style().standardIcon( QStyle.SP_MediaPlay)) def positionChanged(self, position): self.positionSlider.setValue(position) if position > self.endTime: self.mediaPlayer.setPosition(self.startTime) def adjustForStart(self, startPos): self.startTime = startPos self.mediaPlayer.setPosition(startPos) self.startTimeInput.setTime(QtCore.QTime(0, 0).addMSecs(startPos)) self.endTimeInput.setMinimumTime(QtCore.QTime(0, 0).addMSecs(startPos)) def adjustForEnd(self, endPos): self.endTime = endPos if self.positionSlider.value() > endPos: self.mediaPlayer.setPosition(endPos) self.endTimeInput.setTime(QtCore.QTime(0, 0).addMSecs(endPos)) self.startTimeInput.setMaximumTime(QtCore.QTime(0, 0).addMSecs(endPos)) def startInputChanged(self, inputTime): self.rangeSlider.setStart(QtCore.QTime(0, 0, 0, 0).msecsTo(inputTime)) def endInputChanged(self, inputTime): self.rangeSlider.setEnd(QtCore.QTime(0, 0, 0, 0).msecsTo(inputTime)) def durationChanged(self, duration): self.positionSlider.setRange(0, duration) self.rangeSlider.setMax(duration) self.rangeSlider.setEnd(duration) self.startTimeInput.setMinimumTime(QtCore.QTime(0, 0)) self.endTimeInput.setMinimumTime(QtCore.QTime(0, 0)) self.endTimeInput.setTime(QtCore.QTime(0, 0).addMSecs(duration)) self.startTimeInput.setMaximumTime( QtCore.QTime(0, 0).addMSecs(duration)) self.endTimeInput.setMaximumTime(QtCore.QTime(0, 0).addMSecs(duration)) def setPosition(self, position): self.mediaPlayer.setPosition(position)
class MediaCueSettings(SettingsPage): Name = 'Media-Cue' def __init__(self, **kwargs): super().__init__(**kwargs) self.setLayout(QVBoxLayout(self)) # Start time self.startGroup = QGroupBox(self) self.startGroup.setLayout(QHBoxLayout()) self.layout().addWidget(self.startGroup) self.startEdit = QTimeEdit(self.startGroup) self.startEdit.setDisplayFormat('HH.mm.ss.zzz') self.startGroup.layout().addWidget(self.startEdit) self.startLabel = QLabel(self.startGroup) self.startLabel.setAlignment(Qt.AlignCenter) self.startGroup.layout().addWidget(self.startLabel) # Stop time self.stopGroup = QGroupBox(self) self.stopGroup.setLayout(QHBoxLayout()) self.layout().addWidget(self.stopGroup) self.stopEdit = QTimeEdit(self.stopGroup) self.stopEdit.setDisplayFormat('HH.mm.ss.zzz') self.stopGroup.layout().addWidget(self.stopEdit) self.stopLabel = QLabel(self.stopGroup) self.stopLabel.setAlignment(Qt.AlignCenter) self.stopGroup.layout().addWidget(self.stopLabel) # Loop self.loopGroup = QGroupBox(self) self.loopGroup.setLayout(QHBoxLayout()) self.layout().addWidget(self.loopGroup) self.spinLoop = QSpinBox(self.loopGroup) self.spinLoop.setRange(-1, 1000000) self.loopGroup.layout().addWidget(self.spinLoop) self.loopLabel = QLabel(self.loopGroup) self.loopLabel.setAlignment(Qt.AlignCenter) self.loopGroup.layout().addWidget(self.loopLabel) self.retranslateUi() def retranslateUi(self): self.startGroup.setTitle(translate('MediaCueSettings', 'Start time')) self.stopLabel.setText( translate('MediaCueSettings', 'Stop position of the media')) self.stopGroup.setTitle(translate('MediaCueSettings', 'Stop time')) self.startLabel.setText( translate('MediaCueSettings', 'Start position of the media')) self.loopGroup.setTitle(translate('MediaCueSettings', 'Loop')) self.loopLabel.setText( translate('MediaCueSettings', 'Repetition after first play ' '(-1 = infinite)')) def get_settings(self): conf = {'_media_': {}} checkable = self.startGroup.isCheckable() if not (checkable and not self.startGroup.isChecked()): time = self.startEdit.time().msecsSinceStartOfDay() conf['_media_']['start_time'] = time if not (checkable and not self.stopGroup.isChecked()): time = self.stopEdit.time().msecsSinceStartOfDay() conf['_media_']['stop_time'] = time if not (checkable and not self.loopGroup.isChecked()): conf['_media_']['loop'] = self.spinLoop.value() return conf def enable_check(self, enable): self.startGroup.setCheckable(enable) self.startGroup.setChecked(False) self.stopGroup.setCheckable(enable) self.stopGroup.setChecked(False) self.loopGroup.setCheckable(enable) self.loopGroup.setChecked(False) def load_settings(self, settings): if '_media_' in settings: if 'loop' in settings['_media_']: self.spinLoop.setValue(settings['_media_']['loop']) if 'start_time' in settings['_media_']: t = self._to_qtime(settings['_media_']['start_time']) self.startEdit.setTime(t) if 'stop_time' in settings['_media_']: t = self._to_qtime(settings['_media_']['stop_time']) self.stopEdit.setTime(t) t = self._to_qtime(settings['_media_'].get('duration', 0)) self.startEdit.setMaximumTime(t) self.stopEdit.setMaximumTime(t) def _to_qtime(self, m_seconds): return QTime.fromMSecsSinceStartOfDay(m_seconds)
class SongList(QWidget): def __init__(self, parent=None): super(SongList, self).__init__(parent) os.chdir(os.path.dirname(os.path.abspath(__file__))) resourcesPath = os.getcwd() resourcesPath = os.path.join(resourcesPath, "resources") self.PLAY_ICON = QIcon(QPixmap(os.path.join(resourcesPath, "play.png"))) self.PAUSE_ICON = QIcon(QPixmap(os.path.join(resourcesPath, "pause.png"))) self.STOP_ICON = QIcon(QPixmap(os.path.join(resourcesPath, "stop.png"))) self.DELETE_ICON = QIcon(QPixmap(os.path.join(resourcesPath, "delete.png"))) self.setupMediaPlayer() self.setupUi() def setupMediaPlayer(self): self.mediaPlayer = QMediaPlayer() self.mediaPlayer.setNotifyInterval(1) self.mediaPlayer.stateChanged.connect(self.mediaStateChanged) self.mediaPlayer.positionChanged.connect(self.positionChanged) self.mediaPlayer.durationChanged.connect(self.durationChanged) def setupUi(self): self.setWindowTitle("List of songs") mainLayout = QHBoxLayout(self) verticalListLayout = QVBoxLayout() self.songsListWidget = QListWidget() self.songsListWidget.setContextMenuPolicy(Qt.CustomContextMenu) self.songsListWidget.customContextMenuRequested.connect(self.listWidgetRightClick) verticalListLayout.addWidget(self.songsListWidget) miniHorizontalLayout = QHBoxLayout() locatorLine = QLineEdit() locatorLine.setPlaceholderText("Locator") locatorBox = QComboBox() items = ["Title", "Status", "Description", "Style", "All"] locatorBox.addItems(items) locatorBox.setCurrentIndex(len(items)-1) miniHorizontalLayout.addWidget(locatorLine) miniHorizontalLayout.addWidget(locatorBox) locatorLine.textChanged.connect(lambda:self.populateList(locatorLine.text(), locatorBox.currentText())) verticalListLayout.addLayout(miniHorizontalLayout) self.mainForm = QGroupBox() self.mainForm.setTitle("Details") mainLayout.addLayout(verticalListLayout) mainLayout.addWidget(self.mainForm) self.populateList() self.mainFormSetupUi() #self.show() self.songsListWidget.currentRowChanged.connect(self.changePage) def mainFormSetupUi(self): """title, status style, duration, descriptin, location, project, variation_another_song, timestamp""" mainLayout = QVBoxLayout(self.mainForm) #Horizontal Layout 1 horizontalLayout1 = QHBoxLayout() titleLabel = QLabel("Song name:") self.titleEdit = QLineEdit() self.titleEdit.editingFinished.connect(self.checkSong) self.titleEdit.textChanged.connect(self.validateSong) horizontalLayout1.addWidget(titleLabel) horizontalLayout1.addWidget(self.titleEdit) #Horizontal Layout 2 horizontalLayout2 = QHBoxLayout() statusLabel = QLabel("Status:") self.statusBox = QComboBox() dateLabel = QLabel("Date:") self.dateEdit = QDateTimeEdit() self.dateEdit.setCalendarPopup(True) horizontalLayout2.addWidget(statusLabel) horizontalLayout2.addWidget(self.statusBox) horizontalLayout2.addStretch(1) horizontalLayout2.addWidget(dateLabel) horizontalLayout2.addWidget(self.dateEdit) #Style Groupbox, widgets added automatically self.styleGroupBox = QGroupBox() self.styleGroupBox.setTitle("Style:") self.styleLayout = QGridLayout(self.styleGroupBox) horizontalLayout3 = QHBoxLayout() durationLabel = QLabel("Duration:") self.durationLine = QTimeEdit() self.durationLine.setDisplayFormat("mm:ss") projectLabel = QLabel("Project") self.projectComboBox = QComboBox() self.projectComboBox.setEditable(True) horizontalLayout3.addWidget(durationLabel) horizontalLayout3.addWidget(self.durationLine) horizontalLayout3.addWidget(projectLabel) horizontalLayout3.addWidget(self.projectComboBox) horizontalLayout4 = QHBoxLayout() descriptionLabel = QLabel("Description:") variationLabel = QLabel("Variation from another song: ") self.variationLine = QLineEdit() horizontalLayout4.addWidget(descriptionLabel) horizontalLayout4.addStretch(1) horizontalLayout4.addWidget(variationLabel) horizontalLayout4.addWidget(self.variationLine) self.descriptionTextEdit = QTextEdit() horizontalLayout5 = QHBoxLayout() locationLabel = QLabel("Location:") self.locationLine = QLineEdit() self.locationButton = QPushButton("...") self.locationButton.clicked.connect(self.locateFile) horizontalLayout5.addWidget(locationLabel) horizontalLayout5.addWidget(self.locationLine) horizontalLayout5.addWidget(self.locationButton) horizontalLayout6 = QHBoxLayout() self.slider = QSlider(Qt.Horizontal) self.slider.sliderReleased.connect(self.playSlider) self.slider.setStyleSheet("QSlider::handle:horizontal { border: 1px solid #777; background:#b55858;}") horizontalLayout6.addWidget(self.slider) horizontalLayout7 = QHBoxLayout() self.playButton = QPushButton() self.stopButton = QPushButton() self.playButton.setIcon(self.PLAY_ICON) self.stopButton.setIcon(self.STOP_ICON) self.playButton.clicked.connect(self.playSong) self.stopButton.clicked.connect(self.stopSong) horizontalLayout7.addStretch(1) horizontalLayout7.addWidget(self.playButton) horizontalLayout7.addWidget(self.stopButton) horizontalLayout7.addStretch(1) horizontalLayout8 = QHBoxLayout() self.saveButton = QPushButton() self.saveButton.setText("Save") self.saveButton.clicked.connect(self.saveSong) horizontalLayout8.addStretch(1) horizontalLayout8.addWidget(self.saveButton) mainLayout.addLayout(horizontalLayout1) mainLayout.addLayout(horizontalLayout2) mainLayout.addWidget(self.styleGroupBox) mainLayout.addLayout(horizontalLayout3) mainLayout.addLayout(horizontalLayout4) mainLayout.addWidget(self.descriptionTextEdit) mainLayout.addLayout(horizontalLayout5) mainLayout.addLayout(horizontalLayout6) mainLayout.addLayout(horizontalLayout7) mainLayout.addLayout(horizontalLayout8) def clearForm(self): self.titleEdit.clear() self.statusBox.clear() for widget in self.styleGroupBox.children(): if not isinstance(widget, QGridLayout): widget.deleteLater() self.durationLine.clear() self.projectComboBox.clear() self.variationLine.clear() self.descriptionTextEdit.clear() self.locationLine.clear() def changePage(self, index): title = self.songsListWidget.item(index).data(Qt.UserRole) self.clearForm() self.populateForm(title) self.slider.setValue(0) def populateForm(self, title): #title is the primary key listArray = queries("""SELECT title, status, style, duration, description, location, project, variation_another_song, timestamp from songs WHERE title = ?""", (title,)) print(listArray) if len(listArray) != 0: title = listArray[0][0] status = listArray[0][1] styles = [] styleArray = listArray[0][2] if styleArray != None: if "," in styleArray: styles = styleArray.split(",") else: styles.append(styleArray) duration = listArray[0][3] description = listArray[0][4] location = listArray[0][5] project = listArray[0][6] variation_another_song = listArray[0][7] timestamp = listArray[0][8] else: title = None status = None styles = None duration = None description = None location = None project = None variation_another_song = None timestamp = None if title != None: self.titleEdit.setText(title) self.statusBox.addItems(["Select...", "Demo", "WIP", "Idea", "Unfinished song", "EQ", "Master", "Finished"]) if status != None: self.statusBox.setCurrentText(status) if timestamp != None: self.dateEdit.setDateTime(datetime.strptime(timestamp, '%d/%m/%Y %H:%M')) else: self.dateEdit.setDateTime(datetime.now())#default styleArray = queries("select style from songs where style is not null") """ print(styleArray) if styleArray != None: styleArray = styleArray[0][0] if "," in styleArray: styles = styleArray.split(",") else: styles.append(styleArray)""" stylesArray = [] query = queries("select style from songs where style is not null") if len(query) != 0: for style in query: stylesMiniArray = style[0].split(",") stylesMiniArray = list(filter(None, stylesMiniArray)) for item in stylesMiniArray: if item not in stylesArray: if item != '': stylesArray.append(item) self.x = 0 self.y = 0 if len(stylesArray) != 0: for style in stylesArray: print("style", style) checkBox = QCheckBox(style) self.styleLayout.addWidget(checkBox, self.x, self.y) self.checkBoxPositionAsignment() self.addStyle() if styles!= None: if len(styles) != 0: for style in styles: for checkbox in self.styleGroupBox.children(): if isinstance(checkbox, QCheckBox): if checkbox.text() == style: checkbox.setChecked(True) if duration != None: time = QTime(0,0,0) self.durationLine.setTime(time.addSecs(duration)) projectsArray = ["Select..."] projectsArrayQuery = queries("SELECT project from songs") if len(projectsArrayQuery) != 0: for project in projectsArrayQuery[0]: if project not in projectsArray: projectsArray.append(project) if project != None: self.projectComboBox.setCurrentText(project) if variation_another_song != None: self.variationLine.setText(variation_another_song) if description != None: self.descriptionTextEdit.setText(description) available = False if location != None: self.locationLine.setText(location) if len(self.locationLine.text()) != 0: try: self.playlist = QMediaPlaylist() self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(location))) self.mediaPlayer.setPlaylist(self.playlist) except: pass available = True#I know this is stupid but just in case self.slider.setVisible(available) self.playButton.setVisible(available) self.stopButton.setVisible(available) def populateList(self, locatorItem=None, locatorColumn=None): print(locatorItem, locatorColumn) self.songsListWidget.blockSignals(True) self.songsListWidget.clear() if locatorItem == None or locatorItem == "": listArray = queries("""SELECT title, status, timestamp from songs """) print(listArray) else: if locatorColumn != "All": #No strings concatenation, no security holes if locatorColumn == "Title": sql = """SELECT title, status, timestamp from songs where title LIKE ?""" elif locatorColumn == "Status": sql = """SELECT title, status, timestamp from songs where status LIKE ?""" elif locatorColumn == "Description": sql = """SELECT title, status, timestamp from songs where description LIKE ?""" elif locatorColumn == "Style": sql = """SELECT title, status, timestamp from songs where style LIKE ?""" locatorItem = "%" + locatorItem + "%" listArray = queries(sql, (locatorItem,)) else: locatorItem = "%" + locatorItem + "%" variables = [locatorItem, locatorItem, locatorItem, locatorItem, locatorItem] listArray = queries("""SELECT title, status, timestamp from songs where title LIKE ? OR type LIKE ? OR original_song LIKE ? OR link LIKE ? OR description LIKE ?""", variables) for item in listArray: title = item[0] status = item[1] timestamp = item[2] try: timestamp = datetime.strptime(timestamp, "%d/%m/%Y %H:%M") timestamp = timestamp.strftime("%d/%m/%Y") except: timestamp = "" text = "%s %s %s" % (title, status, timestamp) qItem = QListWidgetItem(text) qItem.setData(Qt.UserRole, title) self.songsListWidget.addItem(qItem) #new idea qItem = QListWidgetItem("New song...") qItem.setData(Qt.UserRole, "New song...") #otherwise that would be an error self.songsListWidget.addItem(qItem) self.songsListWidget.blockSignals(False) def listWidgetRightClick(self, position): widgetItem = self.songsListWidget.itemAt(position) if widgetItem != None: #quick lazy text fix if widgetItem.text() != "New song...": print(widgetItem.text()) menu = QMenu() deleteAction = QAction(self.DELETE_ICON, "Delete song") menu.addAction(deleteAction) action = menu.exec(self.mapToGlobal(position)) if action == deleteAction: msg = QMessageBox.question(None, "Delete?", "Are you sure you want to delete this entry?") if msg == QMessageBox.Yes: title = widgetItem.data(Qt.UserRole) queries("DELETE from songs where title = ?", (title,)) self.populateList() self.songsListWidget.setCurrentRow(0) def songVariations(self): sql = "SELECT title from songs" songArray = [] for song in queries(sql)[0]: songArray.append(song) return songArray def checkBoxPositionAsignment(self): self.y += 1 if self.y == 4: self.y = 0 self.x += 1 def addStyle(self, text=""): "text = "" if comes from outside" self.styleEdit = QLineEdit() self.styleEdit.setPlaceholderText("Style") self.styleEdit.textChanged.connect(self.validateStyle) self.styleEdit.returnPressed.connect(lambda: self.addStyle(self.styleEdit.text())) if text != "": self.styleLayout.takeAt(self.styleLayout.count()-1).widget().deleteLater() styleCheckBox = QCheckBox() styleCheckBox.setText(text) print(text) self.styleLayout.addWidget(styleCheckBox, self.x, self.y) self.checkBoxPositionAsignment() print(self.durationLine.text()) self.styleLayout.addWidget(self.styleEdit) def checkSong(self): text = self.titleEdit.text() sql = "SELECT title from songs where title = ?" if len(queries(sql, (text,))) != 0: self.titleEdit.setText("") def validateSong(self): pass #VALIDATE REG EXP def validateStyle(self, text): if "," in text: self.styleEdit.undo() def playSong(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.mediaPlayer.pause() else: self.mediaPlayer.play() def mediaStateChanged(self): if self.mediaPlayer.state() == QMediaPlayer.PlayingState: self.playButton.setIcon(self.PAUSE_ICON) else: self.playButton.setIcon(self.PLAY_ICON) def positionChanged(self, position): if position != self.mediaPlayer.duration(): self.slider.setValue(position) def durationChanged(self, duration): if duration != self.mediaPlayer.position(): print("duration chagned") self.slider.setRange(0, duration) def playSlider(self): self.mediaPlayer.setPosition(self.slider.value()) def stopSong(self): self.mediaPlayer.stop() def locateFile(self): self.fileSystem = QFileDialog(filter="Sound files (*.wav *.mp3 *.flac)") self.fileSystem.show() self.fileSystem.fileSelected.connect(self.fileLoaded) def fileLoaded(self, path): self.locationLine.setText(path) try: self.playlist = QMediaPlaylist() self.playlist.addMedia(QMediaContent(QUrl.fromLocalFile(path))) self.mediaPlayer.setPlaylist(self.playlist) except: print("fail") self.slider.setVisible(True) self.playButton.setVisible(True) self.stopButton.setVisible(True) def saveSong(self): title = self.titleEdit.text() status = self.statusBox.currentText() date = self.dateEdit.text() style = "" print(status, style) x = 0 for checkBox in self.styleGroupBox.children(): if isinstance(checkBox, QCheckBox): if checkBox.isChecked(): style += (checkBox.text()) + "," x+=1 if x != 0: style = style.rstrip(",") else: style = None duration = self.durationLine.time() duration = QTime(0, 0).secsTo(duration) project = self.projectComboBox.currentText() variation = self.variationLine.text() description = self.descriptionTextEdit.toPlainText() location = self.locationLine.text() variables = [title, status, description, location, project,\ variation, date, style, duration] print("---------", variables) sql = """INSERT OR REPLACE into songs (title, status, description, location, project, variation_another_song, timestamp, style, duration) values (?, ?, ?, ?, ?, ?, ?, ?, ?)""" queries(sql, variables) self.populateList()
class SettingsWindow(QMainWindow): def __init__(self, screens): super().__init__() self._init_ui() self.addButton.clicked.connect(self.on_add) self.deleteButton.clicked.connect(self.on_delete) self.upButton.clicked.connect(self.on_up) self.downButton.clicked.connect(self.on_down) self.startButton.clicked.connect(self.on_start) self.saveButton.clicked.connect(self.on_save) self.loadButton.clicked.connect(self.on_load) self.gradientWindowController = GradientWindowController(screens) self._load_settings() def _create_color_tab(self): self.colorWidget = QWidget() self.colorWidget.setAutoFillBackground(True) self.colorsLayout = QHBoxLayout() self.colorTable = QTableWidget() self.colorTable.setRowCount(0) self.colorTable.setColumnCount(1) self.colorTable.verticalHeader().hide() self.colorTable.horizontalHeader().hide() self.colorTable.setMaximumWidth(40) self.colorTable.setColumnWidth(20, 30) self.colorButtonsLayout = QVBoxLayout() self.addButton = QPushButton('Добавить') self.upButton = QPushButton('Вверх') self.downButton = QPushButton('Вниз') self.deleteButton = QPushButton('Удалить') self.colorButtonsLayout.addWidget(self.addButton) self.colorButtonsLayout.addWidget(self.upButton) self.colorButtonsLayout.addWidget(self.downButton) self.colorButtonsLayout.addWidget(self.deleteButton) self.colorButtonsLayout.addStretch() self.colorsLayout.addWidget(self.colorTable) self.colorsLayout.addStretch() self.colorsLayout.addLayout(self.colorButtonsLayout) self.colorWidget.setLayout(self.colorsLayout) return self.colorWidget def _create_intervals_tab(self): self.intervalsWidget = QWidget() self.intervalsWidget.setAutoFillBackground(True) self.intervalsLayout = QVBoxLayout() self.delayInput = QTimeEdit() self.delayInput.setDisplayFormat('hh:mm:ss') self.delayInput.setMinimumTime(QTime(0, 0, 1)) self.repeatInput = QTimeEdit() self.repeatInput.setDisplayFormat('hh:mm:ss') self.repeatInput.setMinimumTime(QTime(0, 0, 1)) self.intervalsLayout.addWidget(QLabel('Первый цвет')) self.intervalsLayout.addWidget(self.delayInput) self.intervalsLayout.addWidget(QLabel('Интервал')) self.intervalsLayout.addWidget(self.repeatInput) self.intervalsLayout.addStretch() self.intervalsWidget.setLayout(self.intervalsLayout) return self.intervalsWidget def _init_ui(self): self.central = QWidget() self.centralLayout = QVBoxLayout() self.tabWidget = QTabWidget() self.tabWidget.addTab(self._create_color_tab(), 'Цвета') self.tabWidget.addTab(self._create_intervals_tab(), 'Интервалы') self.centralLayout.addWidget(self.tabWidget) self.errorLabel = QLabel() self.centralLayout.addWidget(self.errorLabel) self.settingsButtonsLayout = QHBoxLayout() self.saveButton = QPushButton('Сохранить') self.loadButton = QPushButton('Загрузить') self.startButton = QPushButton('Запустить') self.settingsButtonsLayout.addWidget(self.saveButton) self.settingsButtonsLayout.addWidget(self.loadButton) self.settingsButtonsLayout.addWidget(self.startButton) self.centralLayout.addLayout(self.settingsButtonsLayout) self.central.setLayout(self.centralLayout) self.setCentralWidget(self.central) @pyqtSlot() def on_add(self): color = QColorDialog.getColor() item = QTableWidgetItem() item.setBackground(color) table: QTableWidget = self.colorTable table.insertRow(table.rowCount()) table.setItem(table.rowCount() - 1, 0, item) @pyqtSlot() def on_delete(self): table: QTableWidget = self.colorTable selected = table.selectedIndexes() rows = [index.row() for index in selected] for row in rows: table.removeRow(row) @staticmethod def _swap_items(table: QTableWidget, row1, col1, row2, col2): item1 = table.takeItem(row1, col1) item2 = table.takeItem(row2, col2) table.setItem(row1, col1, item2) table.setItem(row2, col2, item1) @pyqtSlot() def on_up(self): table: QTableWidget = self.colorTable selected = table.selectedIndexes() if selected: rows = [index.row() for index in selected] prev_row = 0 for row in sorted(rows): if row > prev_row: SettingsWindow._swap_items(table, row, 0, row - 1, 0) else: prev_row += 1 table.clearSelection() table.setRangeSelected( QTableWidgetSelectionRange(min(rows) - 1, 0, max(rows) - 1, 0), True) @pyqtSlot() def on_down(self): table: QTableWidget = self.colorTable selected = table.selectedIndexes() if selected: rows = [index.row() for index in selected] next_row = table.rowCount() - 1 for row in sorted(rows, reverse=True): if row < next_row: SettingsWindow._swap_items(table, row, 0, row + 1, 0) else: next_row -= 1 table.clearSelection() table.setRangeSelected( QTableWidgetSelectionRange(min(rows) + 1, 0, max(rows) + 1, 0), True) @pyqtSlot() def on_start(self): table: QTableWidget = self.colorTable items = [table.item(row, 0) for row in range(table.rowCount())] colors = [item.background().color() for item in items] if not colors: self.errorLabel.setText('цвета добавь') return if len(colors) < 2: self.errorLabel.setText('давай побольше цветов') return if self.errorLabel.text(): self.errorLabel.setText('молодец') delay = QTime(0, 0).secsTo(self.delayInput.time()) repeat_interval = QTime(0, 0).secsTo(self.repeatInput.time()) self.gradientWindowController.set_colors(colors) self.gradientWindowController.set_timers(delay, repeat_interval) self.gradientWindowController.run() @pyqtSlot() def on_save(self): table: QTableWidget = self.colorTable settings = dict() items = [table.item(row, 0) for row in range(table.rowCount())] colors = [item.background().color() for item in items] rgb_colors = [color.getRgb() for color in colors] settings['colors'] = rgb_colors settings['delay'] = QTime(0, 0).secsTo(self.delayInput.time()) settings['repeat_interval'] = QTime(0, 0).secsTo(self.repeatInput.time()) filename = QFileDialog.getSaveFileName(directory='settings.json')[0] if filename: with open(filename, 'w') as f: json.dump(settings, f) self.errorLabel.setText(f'настройки сохранены в {filename}') def _load_settings(self, filename='settings.json'): try: with open(filename) as f: settings = json.load(f) table: QTableWidget = self.colorTable table.setRowCount(0) for rgb_color in settings['colors']: color = QColor.fromRgb(*rgb_color) item = QTableWidgetItem() item.setBackground(color) table.insertRow(table.rowCount()) table.setItem(table.rowCount() - 1, 0, item) self.delayInput.setTime(QTime(0, 0).addSecs(settings['delay'])) self.repeatInput.setTime( QTime(0, 0).addSecs(settings['repeat_interval'])) self.errorLabel.setText(f'настройки загружены из {filename}') except FileNotFoundError: pass except json.JSONDecodeError or KeyError or TypeError: self.errorLabel.setText(f'в {filename} ошибка') @pyqtSlot() def on_load(self): filename = QFileDialog.getOpenFileName()[0] if filename: self._load_settings(filename)
class StartHandicapDialog(QDialog): def __init__(self): super().__init__(GlobalAccess().get_main_window()) self.time_format = 'hh:mm:ss' self.setWindowTitle(_('Handicap start time')) self.setWindowIcon(QIcon(config.ICON)) self.setSizeGripEnabled(False) self.setModal(True) self.layout = QFormLayout(self) self.handicap_mode = QRadioButton(_('Handicap mode')) self.reverse_mode = QRadioButton(_('Reverse mode')) self.layout.addRow(self.handicap_mode) self.layout.addRow(self.reverse_mode) self.zero_time_label = QLabel(_('Start time')) self.zero_time = QTimeEdit() self.zero_time.setDisplayFormat(self.time_format) self.layout.addRow(self.zero_time_label, self.zero_time) self.max_gap_label = QLabel(_('Max gap from leader')) self.max_gap = QTimeEdit() self.max_gap.setDisplayFormat(self.time_format) self.layout.addRow(self.max_gap_label, self.max_gap) self.second_start_time_label = QLabel(_('Start time for 2 group')) self.second_time = QTimeEdit() self.second_time.setDisplayFormat(self.time_format) self.layout.addRow(self.second_start_time_label, self.second_time) self.interval_time_label = QLabel(_('Start interval')) self.interval_time = QTimeEdit() self.interval_time.setDisplayFormat(self.time_format) self.layout.addRow(self.interval_time_label, self.interval_time) self.dsq_offset_label = QLabel(_('Offset after DSQ')) self.dsq_offset = QTimeEdit() self.dsq_offset.setDisplayFormat(self.time_format) self.layout.addRow(self.dsq_offset_label, self.dsq_offset) def mode_changed(): status = self.handicap_mode.isChecked() self.max_gap.setEnabled(status) self.second_time.setEnabled(status) self.dsq_offset.setDisabled(status) self.handicap_mode.toggled.connect(mode_changed) self.reverse_mode.toggled.connect(mode_changed) def cancel_changes(): self.close() def apply_changes(): try: self.apply_changes_impl() except Exception as e: logging.error(str(e)) logging.exception(e) self.close() button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.button_ok = button_box.button(QDialogButtonBox.Ok) self.button_ok.setText(_('OK')) self.button_ok.clicked.connect(apply_changes) self.button_cancel = button_box.button(QDialogButtonBox.Cancel) self.button_cancel.setText(_('Cancel')) self.button_cancel.clicked.connect(cancel_changes) self.layout.addRow(button_box) self.set_values() self.show() def set_values(self): obj = race() if obj.get_setting('handicap_mode', True): self.handicap_mode.toggle() else: self.reverse_mode.toggle() self.zero_time.setTime( OTime(msec=obj.get_setting('handicap_start', OTime(0, 11).to_msec())).to_time()) self.max_gap.setTime( OTime(msec=obj.get_setting('handicap_max_gap', OTime(0, 0, 30).to_msec())).to_time()) self.second_time.setTime( OTime(msec=obj.get_setting('handicap_second_start', OTime(0, 11, 30).to_msec())).to_time()) self.interval_time.setTime( OTime(msec=obj.get_setting('handicap_interval', OTime(0, 0, 1).to_msec())).to_time()) self.dsq_offset.setTime( OTime(msec=obj.get_setting('handicap_dsq_offset', OTime(0, 0, 10).to_msec())).to_time()) def apply_changes_impl(self): obj = race() obj.set_setting('handicap_mode', self.handicap_mode.isChecked()) obj.set_setting('handicap_start', time_to_otime(self.zero_time.time()).to_msec()) obj.set_setting('handicap_max_gap', time_to_otime(self.max_gap.time()).to_msec()) obj.set_setting('handicap_second_start', time_to_otime(self.second_time.time()).to_msec()) obj.set_setting('handicap_interval', time_to_otime(self.interval_time.time()).to_msec()) obj.set_setting('handicap_dsq_offset', time_to_otime(self.dsq_offset.time()).to_msec()) if obj.get_setting('handicap_mode', True): handicap_start_time() else: reverse_start_time() GlobalAccess().get_main_window().refresh()
class MyTableWidget(QWidget): def __init__(self, parent): super(QWidget, self).__init__(parent) self.layout = QVBoxLayout(self) # Initialize tab screen self.tabs = QTabWidget() self.tab1 = QWidget() self.tab2 = QWidget() self.tab3 = QWidget() self.tabs.resize(300, 200) # Add tabs self.tabs.addTab(self.tab1, "Main Page") self.tabs.addTab(self.tab2, "Add a Meet") self.tabs.addTab(self.tab3, "Eliminar Reunión") # Create first tab self.tab1_layout = QVBoxLayout() self.pushButton1 = QPushButton("Go to class") self.pushButton1.setStyleSheet("font-weight: bold;") self.pushButton1.clicked.connect(self.go_to_class) labelImage = QLabel(self) pixmap = QPixmap("logo.png") labelImage.setPixmap(pixmap) self.tab1_layout.addWidget(labelImage) self.tab1_layout.addWidget(self.pushButton1) self.tab1.setLayout(self.tab1_layout) # Add tabs to widget self.layout.addWidget(self.tabs) self.setLayout(self.layout) self.add_meeting_form() self.deleteTabWidget() self.initial_settings() def add_meeting_form(self): self.days = { "Lunes": "Mon", "Martes": "Tue", "Miércoles": "Wed", "Jueves": "Thu", "Viernes": "Fri", "Sábado": "Sat", "Domingo": "Sun" } self.widgets_group_1 = { "Materia": QLineEdit(), "ID de la reunión": QLineEdit(), "Password": QLineEdit() } # Meeting group data self.group_box = QGroupBox("Datos de la reunión") form_layout = QFormLayout() for name, widget in self.widgets_group_1.items(): form_layout.addRow(name, widget) self.group_box.setLayout(form_layout) # Date grou data self.widgets_group_2 = { "Seleccione un día": QComboBox(), "Seleccione la hora": QTimeEdit(), "Duración (horas)": QSpinBox() } self.group_box2 = QGroupBox("Fecha y Hora") form_layout2 = QFormLayout() self.group_box2.setLayout(form_layout2) for name, widget in self.widgets_group_2.items(): form_layout2.addRow(name, widget) # ComboBox for the days self.widgets_group_2["Seleccione un día"].addItems(self.days.keys()) self.widgets_group_2["Seleccione la hora"].setTime(QTime.currentTime()) self.widgets_group_2["Seleccione la hora"].setDisplayFormat("HH:mm") # https://codetorial.net/en/pyqt5/widget/qtimeedit.html self.widgets_group_2["Duración (horas)"].setMinimum(1) # Tab2 Main Layout self.tab2_layout = QVBoxLayout() self.tab2_layout.addWidget(self.group_box) self.tab2_layout.addWidget(self.group_box2) self.tab2.setLayout(self.tab2_layout) self.get_values_button = QPushButton("Submit") self.get_values_button.setStyleSheet("font-weight: bold;") self.get_values_button.clicked.connect(self.get_values) self.tab2_layout.addWidget(self.get_values_button) def get_values(self): self.values = list() for widget in self.widgets_group_1.values(): if widget.text() == "": QMessageBox.critical(self, "ERROR", "Rellene todos los campos.") break else: self.values.append(widget.text()) if len(self.values) == 3: self.day = self.widgets_group_2["Seleccione un día"].currentText() self.hour_String = self.widgets_group_2["Seleccione la hora"].time( ).toString() self.length = self.widgets_group_2["Duración (horas)"].value() self.time_handler() def time_handler(self): self.hour_list = self.hour_String.split(":") self.hour = self.hour_list[0] try: self.minute = int(self.hour_list[1]) self.hour = int(self.hour_list[0]) except ValueError: self.minute = int(self.hour_list[1][1]) self.hour = int(self.hour_list[0][1]) if self.minute <= 10: self.minMinute = 50 + self.minute self.maxMinute = self.minMinute - 1 self.minHour = self.hour - 1 self.maxHour = self.hour + int(self.length) - 1 else: self.minMinute = self.minute - 10 self.maxMinute = self.minMinute - 1 self.minHour = self.hour self.maxHour = self.hour + int(self.length) self.add_meeting_zoom() def initial_settings(self): self.entry = GoToClass() self.zoom = MeetingDatabase() def go_to_class(self): day, hour, minute = self.entry.get_time() meetid_password = self.zoom.retrieveZoomMeeting(day, hour, minute) if meetid_password is None: QMessageBox.critical(self, "ERROR", "This class doesn't exist.") else: id, password = meetid_password self.entry.robotic_arm(id, password) def add_meeting_zoom(self): self.conn = sqlite3.connect('meetingdatabase.sqlite') self.cur = self.conn.cursor() self.cur.execute( '''INSERT INTO ZoomDatabase (materia, dia, hora, minuto, horaMinima, horaMaxima, minutoMin, minutoMax, IDMeeting, Password) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''', (self.values[0], self.days[self.day], self.hour, self.minute, self.minHour, self.maxHour, self.minMinute, self.maxMinute, self.values[1], self.values[2])) self.conn.commit() self.cur.close() self.delete_items() def delete_items(self): for widget in self.widgets_group_1.values(): widget.setText("") def deleteTabWidget(self): self.deleteSubject = QLineEdit() self.hour_delete = QTimeEdit() self.day_delete = QComboBox() self.day_delete.addItems(self.days.keys()) self.hour_delete.setTime(QTime.currentTime()) self.hour_delete.setDisplayFormat("HH:mm") # Meeting group data self.group_box_delete = QGroupBox("Datos de la reunión a eliminar") delete_form_layout = QFormLayout() delete_form_layout.addRow("Materia:", self.deleteSubject) delete_form_layout.addRow("Día:", self.day_delete) delete_form_layout.addRow("Hora:", self.hour_delete) self.group_box_delete.setLayout(delete_form_layout) #main layout self.tab3_layout = QVBoxLayout() self.tab3_layout.addWidget(self.group_box_delete) self.tab3.setLayout(self.tab3_layout) # Date grou data self.delete_values_button = QPushButton("Eliminar") self.delete_values_button.setStyleSheet("font-weight: bold;") self.delete_values_button.clicked.connect(self.delete_meeting) self.tab3_layout.addWidget(self.delete_values_button) def delete_meeting(self): self.day_to_delete = self.day_delete.currentText() self.hour_String = self.hour_delete.time().toString() self.hour_list = self.hour_String.split(":") self.hour = self.hour_list[0] try: self.hour = int(self.hour_list[0]) except ValueError: self.hour = int(self.hour_list[0][1]) self.subject_to_delete = self.deleteSubject.text() if self.subject_to_delete == "": QMessageBox.critical(self, "ERROR", "Rellene todos los campos.") else: self.conn = sqlite3.connect('meetingdatabase.sqlite') self.cur = self.conn.cursor() self.cur.execute( f"SELECT materia FROM ZoomDatabase WHERE materia='{self.subject_to_delete}' AND dia='{self.days[self.day_to_delete]}' AND hora={self.hour}" ) if self.cur.fetchone() is None: QMessageBox.critical(self, "ERROR", "La reunión no está en la base de datos") else: self.cur.execute( f"DELETE FROM ZoomDatabase WHERE materia='{self.subject_to_delete}' AND dia='{self.days[self.day_to_delete]}' AND hora={self.hour}" ) self.cur.close() self.conn.commit() QMessageBox.information(self, "SUCCESS", "La reunión fue eliminada")
class TimersDialog(QDialog): sendCommand = pyqtSignal(str, str) def __init__(self, device, *args, **kwargs): super(TimersDialog, self).__init__(*args, **kwargs) self.device = device self.timers = {} self.setWindowTitle("Timers [{}]".format( self.device.p['FriendlyName1'])) vl = VLayout() self.gbTimers = GroupBoxV("Enabled", spacing=5) self.gbTimers.setCheckable(True) self.gbTimers.toggled.connect(self.toggleTimers) self.cbTimer = QComboBox() self.cbTimer.addItems(["Timer{}".format(nr + 1) for nr in range(16)]) self.cbTimer.currentTextChanged.connect(self.loadTimer) hl_tmr_arm_rpt = HLayout(0) self.cbTimerArm = QCheckBox("Arm") self.cbTimerArm.clicked.connect(lambda x: self.describeTimer()) self.cbTimerRpt = QCheckBox("Repeat") self.cbTimerRpt.clicked.connect(lambda x: self.describeTimer()) hl_tmr_arm_rpt.addWidgets([self.cbTimerArm, self.cbTimerRpt]) hl_tmr_out_act = HLayout(0) self.cbxTimerOut = QComboBox() self.cbxTimerOut.addItems(self.device.power().keys()) self.cbxTimerOut.currentIndexChanged.connect( lambda x: self.describeTimer()) self.cbxTimerAction = QComboBox() self.cbxTimerAction.addItems(["Off", "On", "Toggle", "Rule"]) self.cbxTimerAction.currentIndexChanged.connect( lambda x: self.describeTimer()) hl_tmr_out_act.addWidgets([self.cbxTimerOut, self.cbxTimerAction]) self.TimerMode = QButtonGroup() rbTime = QRadioButton("Time") rbSunrise = QRadioButton("Sunrise ({})".format( self.device.p['Sunrise'])) rbSunset = QRadioButton("Sunset ({})".format(self.device.p['Sunset'])) self.TimerMode.addButton(rbTime, 0) self.TimerMode.addButton(rbSunrise, 1) self.TimerMode.addButton(rbSunset, 2) self.TimerMode.buttonClicked.connect(lambda x: self.describeTimer()) gbTimerMode = GroupBoxH("Mode") gbTimerMode.addWidgets(self.TimerMode.buttons()) hl_tmr_time = HLayout(0) self.cbxTimerPM = QComboBox() self.cbxTimerPM.addItems(["+", "-"]) self.cbxTimerPM.currentIndexChanged.connect( lambda x: self.describeTimer()) self.TimerMode.buttonClicked[int].connect( lambda x: self.cbxTimerPM.setEnabled(x != 0)) self.teTimerTime = QTimeEdit() self.teTimerTime.setButtonSymbols(QTimeEdit.NoButtons) self.teTimerTime.setAlignment(Qt.AlignCenter) self.teTimerTime.timeChanged.connect(lambda x: self.describeTimer()) lbWnd = QLabel("Window:") lbWnd.setAlignment(Qt.AlignVCenter | Qt.AlignRight) self.cbxTimerWnd = QComboBox() self.cbxTimerWnd.addItems([str(x).zfill(2) for x in range(0, 16)]) self.cbxTimerWnd.currentIndexChanged.connect( lambda x: self.describeTimer()) hl_tmr_days = HLayout(0) self.TimerWeekday = QButtonGroup() self.TimerWeekday.setExclusive(False) for i, wd in enumerate( ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]): cb = QCheckBox(wd) cb.clicked.connect(lambda x: self.describeTimer()) hl_tmr_days.addWidget(cb) self.TimerWeekday.addButton(cb, i) gbTimerDesc = GroupBoxV("Timer description", 5) gbTimerDesc.setMinimumHeight(200) self.lbTimerDesc = QLabel() self.lbTimerDesc.setAlignment(Qt.AlignCenter) self.lbTimerDesc.setWordWrap(True) gbTimerDesc.layout().addWidget(self.lbTimerDesc) hl_tmr_time.addWidgets( [self.cbxTimerPM, self.teTimerTime, lbWnd, self.cbxTimerWnd]) self.gbTimers.layout().addWidget(self.cbTimer) self.gbTimers.layout().addLayout(hl_tmr_arm_rpt) self.gbTimers.layout().addLayout(hl_tmr_out_act) self.gbTimers.layout().addWidget(gbTimerMode) self.gbTimers.layout().addLayout(hl_tmr_time) self.gbTimers.layout().addLayout(hl_tmr_days) btns = QDialogButtonBox(QDialogButtonBox.Save | QDialogButtonBox.Close) reload = btns.addButton("Reload", QDialogButtonBox.ResetRole) btns.accepted.connect(self.saveTimer) btns.rejected.connect(self.reject) reload.clicked.connect( lambda: self.loadTimer(self.cbTimer.currentText())) vl.addWidgets([self.gbTimers, gbTimerDesc, btns]) self.setLayout(vl) def toggleTimers(self, state): self.sendCommand.emit(self.device.cmnd_topic('timers'), "ON" if state else "OFF") def loadTimer(self, timer=""): if not timer: timer = self.cbTimer.currentText() payload = self.timers[timer] if payload: self.blockSignals(True) self.cbTimerArm.setChecked(payload['Arm']) self.cbTimerRpt.setChecked(payload['Repeat']) self.cbxTimerAction.setCurrentIndex(payload['Action']) output = payload.get('Output') if output: self.cbxTimerOut.setEnabled(True) self.cbxTimerOut.setCurrentIndex(output - 1) else: self.cbxTimerOut.setEnabled(False) mode = payload.get('Mode', 0) self.TimerMode.button(mode).setChecked(True) h, m = map(int, payload["Time"].split(":")) if h < 0: self.cbxTimerPM.setCurrentText("-") h *= -1 self.teTimerTime.setTime(QTime(h, m)) self.cbxTimerWnd.setCurrentText(str(payload['Window']).zfill(2)) for wd, v in enumerate(payload['Days']): self.TimerWeekday.button(wd).setChecked(int(v)) self.blockSignals(False) self.describeTimer() def describeTimer(self): if self.cbTimerArm.isChecked(): desc = { 'days': '', 'repeat': '', 'timer': self.cbTimer.currentText().upper() } repeat = self.cbTimerRpt.isChecked() out = self.cbxTimerOut.currentText() act = self.cbxTimerAction.currentText() mode = self.TimerMode.checkedId() pm = self.cbxTimerPM.currentText() time = self.teTimerTime.time() wnd = int(self.cbxTimerWnd.currentText()) * 60 if mode == 0: if wnd == 0: desc['time'] = "at {}".format(time.toString("hh:mm")) else: desc['time'] = "somewhere between {} and {}".format( time.addSecs(wnd * -1).toString("hh:mm"), time.addSecs(wnd).toString("hh:mm")) else: prefix = "before" if pm == "-" else "after" mode_desc = "sunrise" if mode == 1 else "sunset" window = "somewhere in a {} minute window centered around ".format( wnd // 30) desc['time'] = "{}h{}m {} {}".format(time.hour(), time.minute(), prefix, mode_desc) if wnd > 0: desc['time'] = window + desc['time'] if repeat: day_names = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"] days = [cb.isChecked() for cb in self.TimerWeekday.buttons()] if days.count(True) == 7: desc['days'] = "everyday" else: days_list = [day_names[d] for d in range(7) if days[d]] desc['days'] = "on every {}".format(", ".join(days_list)) else: desc['repeat'] = "only ONCE" if act == "Rule": desc['action'] = "trigger clock#Timer={}".format( self.cbTimer.currentIndex() + 1) text = "{timer} will {action} {time} {days} {repeat}".format( **desc) elif self.cbxTimerOut.count() > 0: if act == "Toggle": desc['action'] = "TOGGLE {}".format(out.upper()) else: desc['action'] = "set {} to {}".format( out.upper(), act.upper()) text = "{timer} will {action} {time} {days} {repeat}".format( **desc) else: text = "{timer} will do nothing because there are no relays configured.".format( **desc) self.lbTimerDesc.setText(text) else: self.lbTimerDesc.setText( "{} is not armed, it will do nothing.".format( self.cbTimer.currentText().upper())) def saveTimer(self): payload = { "Arm": int(self.cbTimerArm.isChecked()), "Mode": self.TimerMode.checkedId(), "Time": self.teTimerTime.time().toString("hh:mm"), "Window": self.cbxTimerWnd.currentIndex(), "Days": "".join([ str(int(cb.isChecked())) for cb in self.TimerWeekday.buttons() ]), "Repeat": int(self.cbTimerRpt.isChecked()), "Output": self.cbxTimerOut.currentIndex() + 1, "Action": self.cbxTimerAction.currentIndex() } self.sendCommand.emit( self.device.cmnd_topic(self.cbTimer.currentText()), dumps(payload)) QMessageBox.information( self, "Timer saved", "{} data sent to device.".format(self.cbTimer.currentText())) @pyqtSlot(str, str) def parseMessage(self, topic, msg): if self.device.matches(topic): if self.device.reply == "RESULT" or self.device.reply == "TIMERS": try: payload = loads(msg) first = list(payload)[0] except JSONDecodeError as e: error = "Timer loading error", "Can't load the timer from device.\n{}".format( e) logging.critical(error) QMessageBox.critical(self, error) else: if first == 'Timers': self.gbTimers.setChecked(payload[first] == "ON") elif first.startswith('Timers'): self.timers.update(payload[first]) if first == 'Timers4': self.loadTimer(self.cbTimer.currentText())
class Example(QWidget): def __init__(self): super().__init__() self.clear_lineedit = QLineEdit(self) self.info_sort = '' self.list = [] self.dict = {} self.flag_print_file_info = True self.initUI() def initUI(self): self.setGeometry(300, 300, 940, 650) self.setWindowTitle('Первая программа') self.myListView = QListView(self) self.myListView.resize(300, 500) self.myListView.move(600, 0) self.cal = QCalendarWidget(self) self.cal.resize(500, 500) self.cal.move(0, 0) self.time = QTimeEdit(self) self.time.resize(50, 50) self.time.move(520, 250) self.helps = QLabel('Введите событие:', self) self.helps.move(0, 530) self.input_ivents = QLineEdit(self) self.input_ivents.resize(200, 50) self.input_ivents.move(130, 520) self.setStyleSheet("QLabel { font-size:15px}") self.button = QPushButton('Добавить', self) self.button.move(80, 580) self.print_file_info() self.button.clicked.connect(self.push) self.show() def print_file_info(self): if len(z) > 1: for x in range(len(z)): x = z[x].split() self.dict[x[1]] = x[0] x = x[1].split('.') x = ''.join(x) self.list.append(x) elif len(z) == 2: x = z[0].split() self.dict[x[1]] = x[0] x = x[1].split('.') x = ''.join(x) self.list.append(x) if self.flag_print_file_info: for x in range(len(self.list)): self.list[x] = int(self.list[x]) self.list.sort() model = QtGui.QStandardItemModel() self.myListView.setModel(model) for x in range(len(self.list)): self.list[x] = str(self.list[x]) for e in self.list: for x in self.dict.keys(): if ''.join(x.split('.')) == str(e): p = x.split('.') i = QtGui.QStandardItem(self.dict[x] + ' ' + p[2] + '.' + p[1] + '.' + p[0] + ' ' + p[3] + ':' + p[-1]) model.appendRow(i) self.show() self.flag_print_file_info = False def push(self): time: QTime = self.time.time() self.ivent = self.input_ivents.text() self.info_input = '' date: QDate = self.cal.selectedDate() self.info_input += str(date.year()) + '.' self.info_sort += str(date.year()) if len(str(date.month())) == 1: self.info_input += '0' + str(date.month()) + '.' self.info_sort += '0' + str(date.month()) else: self.info_input += str(date.month()) + '.' self.info_sort += str(date.month()) if len(str(date.day())) == 1: self.info_input += '0' + str(date.day()) + '.' self.info_sort += '0' + str(date.day()) else: self.info_input += str(date.day()) + '.' self.info_sort += str(date.day()) if len(str(time.hour())) == 1: self.info_input += '0' + str(time.hour()) + '.' self.info_sort += '0' + str(time.hour()) else: self.info_input += str(time.hour()) + '.' self.info_sort += str(time.hour()) if len(str(time.minute())) == 1: self.info_input += '0' + str(time.minute()) self.info_sort += '0' + str(time.minute()) else: self.info_input += str(time.minute()) self.info_sort += str(time.minute()) self.info_sort = int(self.info_sort) self.list.append(self.info_sort) self.dict[self.info_input] = self.ivent for x in range(len(self.list)): self.list[x] = int(self.list[x]) self.list.sort() self.info_sort = '' model = QtGui.QStandardItemModel() self.myListView.setModel(model) for x in range(len(self.list)): self.list[x] = str(self.list[x]) for e in self.list: for x in self.dict.keys(): if ''.join(x.split('.')) == str(e): p = x.split('.') i = QtGui.QStandardItem(self.dict[x] + ' ' + p[2] + '.' + p[1] + '.' + p[0] + ' ' + p[3] + ':' + p[-1]) model.appendRow(i) with open('file.txt', 'w', encoding='utf-8') as g: g.seek(0) for x in self.dict.keys(): g.write(self.dict[x] + ' ' + x + '\n') g.close()
class MediaCueSettings(SettingsPage): Name = 'Media-Cue' def __init__(self, **kwargs): super().__init__(**kwargs) self.setLayout(QVBoxLayout(self)) # Start time self.startGroup = QGroupBox(self) self.startGroup.setLayout(QHBoxLayout()) self.layout().addWidget(self.startGroup) self.startEdit = QTimeEdit(self.startGroup) self.startEdit.setDisplayFormat('HH.mm.ss.zzz') self.startGroup.layout().addWidget(self.startEdit) self.startLabel = QLabel(self.startGroup) self.startLabel.setAlignment(Qt.AlignCenter) self.startGroup.layout().addWidget(self.startLabel) # Stop time self.stopGroup = QGroupBox(self) self.stopGroup.setLayout(QHBoxLayout()) self.layout().addWidget(self.stopGroup) self.stopEdit = QTimeEdit(self.stopGroup) self.stopEdit.setDisplayFormat('HH.mm.ss.zzz') self.stopGroup.layout().addWidget(self.stopEdit) self.stopLabel = QLabel(self.stopGroup) self.stopLabel.setAlignment(Qt.AlignCenter) self.stopGroup.layout().addWidget(self.stopLabel) # Loop self.loopGroup = QGroupBox(self) self.loopGroup.setLayout(QHBoxLayout()) self.layout().addWidget(self.loopGroup) self.spinLoop = QSpinBox(self.loopGroup) self.spinLoop.setRange(-1, 1000000) self.loopGroup.layout().addWidget(self.spinLoop) self.loopLabel = QLabel(self.loopGroup) self.loopLabel.setAlignment(Qt.AlignCenter) self.loopGroup.layout().addWidget(self.loopLabel) self.retranslateUi() def retranslateUi(self): self.startGroup.setTitle('Start time') self.stopLabel.setText('Stop position of the media') self.stopGroup.setTitle('Stop time') self.startLabel.setText('Start position of the media') self.loopGroup.setTitle('Loop') self.loopLabel.setText('Repetition after first play (-1 = infinite)') def get_settings(self): conf = {'_media_': {}} checkable = self.startGroup.isCheckable() if not (checkable and not self.startGroup.isChecked()): time = self.startEdit.time().msecsSinceStartOfDay() conf['_media_']['start_time'] = time if not (checkable and not self.stopGroup.isChecked()): time = self.stopEdit.time().msecsSinceStartOfDay() conf['_media_']['stop_time'] = time if not (checkable and not self.loopGroup.isChecked()): conf['_media_']['loop'] = self.spinLoop.value() return conf def enable_check(self, enable): self.startGroup.setCheckable(enable) self.startGroup.setChecked(False) self.stopGroup.setCheckable(enable) self.stopGroup.setChecked(False) self.loopGroup.setCheckable(enable) self.loopGroup.setChecked(False) def load_settings(self, settings): if '_media_' in settings: if 'loop' in settings['_media_']: self.spinLoop.setValue(settings['_media_']['loop']) if 'start_time' in settings['_media_']: t = self._to_qtime(settings['_media_']['start_time']) self.startEdit.setTime(t) if 'stop_time' in settings['_media_']: t = self._to_qtime(settings['_media_']['stop_time']) self.stopEdit.setTime(t) t = self._to_qtime(settings['_media_'].get('duration', 0)) self.startEdit.setMaximumTime(t) self.stopEdit.setMaximumTime(t) def _to_qtime(self, m_seconds): return QTime.fromMSecsSinceStartOfDay(m_seconds)
class GroupEditDialog(QDialog): def __init__(self, group, is_new=False): super().__init__(GlobalAccess().get_main_window()) assert (isinstance(group, Group)) self.current_object = group self.is_new = is_new self.time_format = 'hh:mm:ss' def exec(self): self.init_ui() self.set_values_from_model() return super().exec() def init_ui(self): self.setWindowTitle(_('Group properties')) self.setWindowIcon(QIcon(config.ICON)) self.setSizeGripEnabled(False) self.setModal(True) self.layout = QFormLayout(self) self.label_name = QLabel(_('Name')) self.item_name = QLineEdit() self.item_name.textChanged.connect(self.check_name) self.layout.addRow(self.label_name, self.item_name) self.label_full_name = QLabel(_('Full name')) self.item_full_name = QLineEdit() self.layout.addRow(self.label_full_name, self.item_full_name) self.label_course = QLabel(_('Course')) self.item_course = AdvComboBox() self.item_course.addItems(get_race_courses()) self.layout.addRow(self.label_course, self.item_course) self.label_is_any_course = QLabel(_('Is any course')) self.item_is_any_course = QCheckBox() self.item_is_any_course.stateChanged.connect(self.is_any_course_update) self.layout.addRow(self.label_is_any_course, self.item_is_any_course) self.label_sex = QLabel(_('Sex')) self.item_sex = AdvComboBox() self.item_sex.addItems(Sex.get_titles()) self.layout.addRow(self.label_sex, self.item_sex) self.label_age_min = QLabel(_('Min age')) self.item_age_min = QSpinBox() # self.layout.addRow(self.label_age_min, self.item_age_min) self.label_age_max = QLabel(_('Max age')) self.item_age_max = QSpinBox() # self.layout.addRow(self.label_age_max, self.item_age_max) self.label_year_min = QLabel(_('Min year')) self.item_year_min = QSpinBox() self.item_year_min.setMaximum(date.today().year) self.item_year_min.editingFinished.connect(self.year_change) self.layout.addRow(self.label_year_min, self.item_year_min) self.label_year_max = QLabel(_('Max year')) self.item_year_max = QSpinBox() self.item_year_max.setMaximum(date.today().year) self.item_year_max.editingFinished.connect(self.year_change) self.layout.addRow(self.label_year_max, self.item_year_max) self.label_max_time = QLabel(_('Max time')) self.item_max_time = QTimeEdit() self.item_max_time.setDisplayFormat(self.time_format) self.layout.addRow(self.label_max_time, self.item_max_time) self.label_corridor = QLabel(_('Start corridor')) self.item_corridor = QSpinBox() self.layout.addRow(self.label_corridor, self.item_corridor) self.label_corridor_order = QLabel(_('Order in corridor')) self.item_corridor_order = QSpinBox() self.layout.addRow(self.label_corridor_order, self.item_corridor_order) self.label_start_interval = QLabel(_('Start interval')) self.item_start_interval = QTimeEdit() self.item_start_interval.setDisplayFormat(self.time_format) self.layout.addRow(self.label_start_interval, self.item_start_interval) self.label_price = QLabel(_('Start fee')) self.item_price = QSpinBox() self.item_price.setSingleStep(50) self.item_price.setMaximum(Limit.PRICE) self.layout.addRow(self.label_price, self.item_price) self.type_label = QLabel(_('Type')) self.type_combo = AdvComboBox() self.type_combo.addItems(RaceType.get_titles()) self.layout.addRow(self.type_label, self.type_combo) self.rank_checkbox = QCheckBox(_('Rank calculation')) self.rank_button = QPushButton(_('Configuration')) self.layout.addRow(self.rank_checkbox, self.rank_button) def cancel_changes(): self.close() def apply_changes(): try: self.apply_changes_impl() except Exception as e: logging.error(str(e)) self.close() button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) self.button_ok = button_box.button(QDialogButtonBox.Ok) self.button_ok.setText(_('OK')) self.button_ok.clicked.connect(apply_changes) self.button_cancel = button_box.button(QDialogButtonBox.Cancel) self.button_cancel.setText(_('Cancel')) self.button_cancel.clicked.connect(cancel_changes) self.layout.addRow(button_box) self.show() self.button_ok.setFocus() def check_name(self): name = self.item_name.text() self.button_ok.setDisabled(False) if name and name != self.current_object.name: group = find(race().groups, name=name) if group: self.button_ok.setDisabled(True) def year_change(self): """ Convert 2 digits of year to 4 2 -> 2002 11 - > 2011 33 -> 1933 56 -> 1956 98 - > 1998 0 -> 0 exception! """ widget = self.sender() assert isinstance(widget, QSpinBox) year = widget.value() if 0 < year < 100: cur_year = date.today().year new_year = cur_year - cur_year % 100 + year if new_year > cur_year: new_year -= 100 widget.setValue(new_year) def is_any_course_update(self): if self.item_is_any_course.isChecked(): self.item_course.setDisabled(True) else: self.item_course.setDisabled(False) def set_values_from_model(self): self.item_name.setText(self.current_object.name) if self.current_object.long_name: self.item_full_name.setText(self.current_object.long_name) if self.current_object.course: self.item_course.setCurrentText(self.current_object.course.name) if self.current_object.sex: self.item_sex.setCurrentText(self.current_object.sex.get_title()) if self.current_object.min_age: self.item_age_min.setValue(self.current_object.min_age) if self.current_object.max_age: self.item_age_max.setValue(self.current_object.max_age) if self.current_object.min_year: self.item_year_min.setValue(self.current_object.min_year) if self.current_object.max_year: self.item_year_max.setValue(self.current_object.max_year) if self.current_object.max_time: self.item_max_time.setTime( time_to_qtime(self.current_object.max_time)) if self.current_object.start_interval: self.item_start_interval.setTime( time_to_qtime(self.current_object.start_interval)) if self.current_object.start_corridor: self.item_corridor.setValue(self.current_object.start_corridor) if self.current_object.order_in_corridor: self.item_corridor_order.setValue( self.current_object.order_in_corridor) if self.current_object.price: self.item_price.setValue(self.current_object.price) self.item_is_any_course.setChecked(self.current_object.is_any_course) self.rank_checkbox.setChecked(self.current_object.ranking.is_active) self.type_combo.setCurrentText(race().get_type( self.current_object).get_title()) def rank_configuration(): group = self.current_object GroupRankingDialog(group).exec() self.rank_button.clicked.connect(rank_configuration) def apply_changes_impl(self): group = self.current_object assert (isinstance(group, Group)) if self.is_new: race().groups.insert(0, group) if group.name != self.item_name.text(): group.name = self.item_name.text() if group.long_name != self.item_full_name.text(): group.long_name = self.item_full_name.text() if (group.course is not None and group.course.name != self.item_course.currentText()) \ or (group.course is None and len(self.item_course.currentText()) > 0): group.course = find(race().courses, name=self.item_course.currentText()) if group.sex.get_title() != self.item_sex.currentText(): group.sex = Sex(self.item_sex.currentIndex()) if group.min_age != self.item_age_min.value(): group.min_age = self.item_age_min.value() if group.max_age != self.item_age_max.value(): group.max_age = self.item_age_max.value() if group.min_year != self.item_year_min.value(): group.min_year = self.item_year_min.value() if group.max_year != self.item_year_max.value(): group.max_year = self.item_year_max.value() if group.start_corridor != self.item_corridor.value(): group.start_corridor = self.item_corridor.value() if group.order_in_corridor != self.item_corridor_order.value(): group.order_in_corridor = self.item_corridor_order.value() if group.price != self.item_price.value(): group.price = self.item_price.value() time = time_to_otime(self.item_start_interval.time()) if group.start_interval != time: group.start_interval = time time = time_to_otime(self.item_max_time.time()) if group.max_time != time: group.max_time = time if group.ranking.is_active != self.rank_checkbox.isChecked(): group.ranking.is_active = self.rank_checkbox.isChecked() t = RaceType.get_by_name(self.type_combo.currentText()) selected_type = t if t is not None else group.get_type() if group.get_type() != selected_type: group.set_type(selected_type) group.is_any_course = self.item_is_any_course.isChecked() ResultCalculation(race()).set_rank(group) GlobalAccess().get_main_window().refresh() Teamwork().send(group.to_dict())