def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.search_bar = QLineEdit() search_bar_layout = QHBoxLayout() search_bar_layout.addWidget(QLabel('Custom Query:')) search_bar_layout.addWidget(self.search_bar) mongo_query_help_button = QPushButton() mongo_query_help_button.setText('?') search_bar_layout.addWidget(mongo_query_help_button) mongo_query_help_button.clicked.connect(self.show_mongo_query_help) self.since_widget = QDateTimeEdit() self.since_widget.setCalendarPopup(True) self.since_widget.setDisplayFormat('yyyy-MM-dd HH:mm') since_layout = QHBoxLayout() since_layout.addWidget(QLabel('Since:')) since_layout.addWidget(self.since_widget) self.until_widget = QDateTimeEdit() self.until_widget.setCalendarPopup(True) self.until_widget.setDisplayFormat('yyyy-MM-dd HH:mm') until_layout = QHBoxLayout() until_layout.addWidget(QLabel('Until:')) until_layout.addWidget(self.until_widget) layout = QVBoxLayout() layout.addLayout(since_layout) layout.addLayout(until_layout) layout.addLayout(search_bar_layout) self.setLayout(layout)
def _setupTimePeriodSelWidget(self): tnow = Time.now() ld_tstart = QLabel('Time start: ') self.dt_start = QDateTimeEdit(tnow - 10 * 60, self) self.dt_start.setCalendarPopup(True) self.dt_start.setMinimumDate(Time(2020, 1, 1)) self.dt_start.setDisplayFormat('dd/MM/yyyy hh:mm') ld_tstop = QLabel('Time stop: ') self.dt_stop = QDateTimeEdit(tnow, self) self.dt_stop.setCalendarPopup(True) self.dt_stop.setMinimumDate(Time(2020, 1, 1)) self.dt_stop.setDisplayFormat('dd/MM/yyyy hh:mm') self.pb_search = QPushButton(qta.icon('fa5s.search'), 'Search', self) self.pb_search.clicked.connect(self._do_update) self.pb_search.setObjectName('pb_search') self.pb_search.setStyleSheet(""" #pb_search{ min-width:100px; max-width:100px; min-height:25px; max-height:25px; icon-size:20px;} """) wid = QGroupBox('Select interval: ', self) lay = QGridLayout(wid) lay.addWidget(ld_tstart, 0, 0) lay.addWidget(self.dt_start, 0, 1) lay.addWidget(ld_tstop, 1, 0) lay.addWidget(self.dt_stop, 1, 1) lay.addWidget(self.pb_search, 2, 1, alignment=Qt.AlignRight) return wid
def createBottomRightGroupBox(self): self.bottomRightGroupBox = QGroupBox("Group 3") self.bottomRightGroupBox.setCheckable(True) self.bottomRightGroupBox.setChecked(True) lineEdit = QLineEdit('s3cRe7') lineEdit.setEchoMode(QLineEdit.Password) spinBox = QSpinBox(self.bottomRightGroupBox) spinBox.setValue(50) dateTimeEdit = QDateTimeEdit(self.bottomRightGroupBox) dateTimeEdit.setDateTime(QDateTime.currentDateTime()) slider = QSlider(Qt.Horizontal, self.bottomRightGroupBox) slider.setValue(40) scrollBar = QScrollBar(Qt.Horizontal, self.bottomRightGroupBox) scrollBar.setValue(60) dial = QDial(self.bottomRightGroupBox) dial.setValue(30) dial.setNotchesVisible(True) layout = QGridLayout() layout.addWidget(lineEdit, 0, 0, 1, 2) layout.addWidget(spinBox, 1, 0, 1, 2) layout.addWidget(dateTimeEdit, 2, 0, 1, 2) layout.addWidget(slider, 3, 0) layout.addWidget(scrollBar, 4, 0) layout.addWidget(dial, 3, 1, 2, 1) layout.setRowStretch(5, 1) self.bottomRightGroupBox.setLayout(layout)
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.search_bar = QLineEdit() search_bar_layout = QHBoxLayout() search_bar_layout.addWidget(QLabel('Custom Query:')) search_bar_layout.addWidget(self.search_bar) mongo_query_help_button = QPushButton() mongo_query_help_button.setText('?') search_bar_layout.addWidget(mongo_query_help_button) mongo_query_help_button.clicked.connect(self.show_mongo_query_help) self.since_widget = QDateTimeEdit() self.since_widget.setCalendarPopup(True) self.since_widget.setDisplayFormat('yyyy-MM-dd HH:mm') since_layout = QHBoxLayout() since_layout.addWidget(QLabel('Since:')) since_layout.addWidget(self.since_widget) self.until_widget = QDateTimeEdit() self.until_widget.setCalendarPopup(True) self.until_widget.setDisplayFormat('yyyy-MM-dd HH:mm') until_layout = QHBoxLayout() until_layout.addWidget(QLabel('Until:')) until_layout.addWidget(self.until_widget) layout = QVBoxLayout() layout.addLayout(since_layout) layout.addLayout(until_layout) layout.addLayout(search_bar_layout) self.setLayout(layout)
class TaskOptionsGroupBox(QGroupBox): def __init__(self, parent): super(TaskOptionsGroupBox, self).__init__(parent) self.widget_layout = QFormLayout(self) self.setLayout(self.widget_layout) self.setTitle("Time") self.time_label = QLabel(self) self.time_label.setText("Execute: ") self.time_now = QRadioButton(self) self.time_now.setText("Immediately") self.time_now.setChecked(True) self.time_schedule = QRadioButton(self) self.time_schedule.setText("Schedule") self.schedule_select = QDateTimeEdit(self) self.schedule_select.setDateTime(QDateTime.currentDateTime()) self.schedule_select.setEnabled(False) self.user_activity_label = QLabel(self) self.user_activity_label.setText("User activity") self.user_activity_combo = QComboBox(self) self.user_activity_combo.addItems([ "0 - Disabled", "1 - Low", "2 - Normal", "3 - Medium", "4 - High", "5 - Very high" ]) self.widget_layout.addRow(self.time_label, None) self.widget_layout.addRow(self.time_now, None) self.widget_layout.addRow(self.time_schedule, self.schedule_select) self.widget_layout.addRow(self.user_activity_label, self.user_activity_combo) self.time_schedule.toggled.connect(self.on_time_schedule_toggled) @Slot(bool) def on_time_schedule_toggled(self, state): if state: self.schedule_select.setEnabled(True) else: self.schedule_select.setEnabled(False) def get_options(self): resp = { "user_activity": self.user_activity_combo.currentText().split(" - ")[0] } if self.time_now.isChecked(): resp["time"] = "now" elif self.time_schedule.isChecked(): resp["time"] = self.schedule_select.dateTime().toString() return resp
class SearchInputWidget(QWidget): """ Input fields for specifying searches on SearchResultsModel """ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.search_bar = QLineEdit() search_bar_layout = QHBoxLayout() search_bar_layout.addWidget(QLabel('Custom Query:')) search_bar_layout.addWidget(self.search_bar) mongo_query_help_button = QPushButton() mongo_query_help_button.setText('?') search_bar_layout.addWidget(mongo_query_help_button) mongo_query_help_button.clicked.connect(self.show_mongo_query_help) self.since_widget = QDateTimeEdit() self.since_widget.setCalendarPopup(True) self.since_widget.setDisplayFormat('yyyy-MM-dd HH:mm') since_layout = QHBoxLayout() since_layout.addWidget(QLabel('Since:')) since_layout.addWidget(self.since_widget) self.until_widget = QDateTimeEdit() self.until_widget.setCalendarPopup(True) self.until_widget.setDisplayFormat('yyyy-MM-dd HH:mm') until_layout = QHBoxLayout() until_layout.addWidget(QLabel('Until:')) until_layout.addWidget(self.until_widget) layout = QVBoxLayout() layout.addLayout(since_layout) layout.addLayout(until_layout) layout.addLayout(search_bar_layout) self.setLayout(layout) def mark_custom_query(self, valid): "Indicate whether the current text is a parsable query." if valid: stylesheet = GOOD_TEXT_INPUT else: stylesheet = BAD_TEXT_INPUT self.search_bar.setStyleSheet(stylesheet) def show_mongo_query_help(self): "Launch a Message Box with instructions for custom queries." msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText( "For advanced search capability, enter a valid Mongo query.") msg.setInformativeText(""" Examples: {'plan_name': 'scan'} {'proposal': 1234}, {'$and': ['proposal': 1234, 'sample_name': 'Ni']} """) msg.setWindowTitle("Custom Mongo Query") msg.setStandardButtons(QMessageBox.Ok) msg.exec_()
class SearchInputWidget(QWidget): """ Input fields for specifying searches on SearchResultsModel """ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.search_bar = QLineEdit() search_bar_layout = QHBoxLayout() search_bar_layout.addWidget(QLabel('Custom Query:')) search_bar_layout.addWidget(self.search_bar) mongo_query_help_button = QPushButton() mongo_query_help_button.setText('?') search_bar_layout.addWidget(mongo_query_help_button) mongo_query_help_button.clicked.connect(self.show_mongo_query_help) self.since_widget = QDateTimeEdit() self.since_widget.setCalendarPopup(True) self.since_widget.setDisplayFormat('yyyy-MM-dd HH:mm') since_layout = QHBoxLayout() since_layout.addWidget(QLabel('Since:')) since_layout.addWidget(self.since_widget) self.until_widget = QDateTimeEdit() self.until_widget.setCalendarPopup(True) self.until_widget.setDisplayFormat('yyyy-MM-dd HH:mm') until_layout = QHBoxLayout() until_layout.addWidget(QLabel('Until:')) until_layout.addWidget(self.until_widget) layout = QVBoxLayout() layout.addLayout(since_layout) layout.addLayout(until_layout) layout.addLayout(search_bar_layout) self.setLayout(layout) def mark_custom_query(self, valid): "Indicate whether the current text is a parsable query." if valid: stylesheet = GOOD_TEXT_INPUT else: stylesheet = BAD_TEXT_INPUT self.search_bar.setStyleSheet(stylesheet) def show_mongo_query_help(self): "Launch a Message Box with instructions for custom queries." msg = QMessageBox() msg.setIcon(QMessageBox.Information) msg.setText("For advanced search capability, enter a valid Mongo query.") msg.setInformativeText(""" Examples: {'plan_name': 'scan'} {'proposal': 1234}, {'$and': ['proposal': 1234, 'sample_name': 'Ni']} """) msg.setWindowTitle("Custom Mongo Query") msg.setStandardButtons(QMessageBox.Ok) msg.exec_()
def __init__(self, model, *args, **kwargs): self.model = model super().__init__(*args, **kwargs) # "Since: <datetime picker>" self.since_widget = QDateTimeEdit() self.since_widget.setCalendarPopup(True) self.since_widget.setDisplayFormat("yyyy-MM-dd HH:mm") since_layout = QHBoxLayout() since_layout.addWidget(QLabel("Since:")) since_layout.addWidget(self.since_widget) since_layout_widget = QWidget() since_layout_widget.setLayout(since_layout) # "Until: <datetime picker>" self.until_widget = QDateTimeEdit() self.until_widget.setCalendarPopup(True) self.until_widget.setDisplayFormat("yyyy-MM-dd HH:mm") until_layout = QHBoxLayout() until_layout.addWidget(QLabel("Until:")) until_layout.addWidget(self.until_widget) until_layout_widget = QWidget() until_layout_widget.setLayout(until_layout) self.refresh_button = QPushButton("Refresh") # Stack them up. layout = QVBoxLayout() layout.addWidget(since_layout_widget) layout.addWidget(until_layout_widget) layout.addWidget(self.refresh_button) self.setLayout(layout) # Initialize values. qdatetime = QDateTime() qdatetime.setSecsSinceEpoch(self.model.since) self.since_widget.setDateTime(qdatetime) qdatetime = QDateTime() qdatetime.setSecsSinceEpoch(self.model.until) self.until_widget.setDateTime(qdatetime) # Changes to the GUI update the model. self.since_widget.dateTimeChanged.connect(self.on_since_view_changed) self.until_widget.dateTimeChanged.connect(self.on_until_view_changed) self.refresh_button.clicked.connect(self.model.events.reload) # Changes to the model update the GUI. self.model.events.since.connect(self.on_since_model_changed) self.model.events.until.connect(self.on_until_model_changed)
def __init__(self, parent): super(TaskOptionsGroupBox, self).__init__(parent) self.widget_layout = QFormLayout(self) self.setLayout(self.widget_layout) self.setTitle("Time") self.time_label = QLabel(self) self.time_label.setText("Execute: ") self.time_now = QRadioButton(self) self.time_now.setText("Immediately") self.time_now.setChecked(True) self.time_schedule = QRadioButton(self) self.time_schedule.setText("Schedule") self.schedule_select = QDateTimeEdit(self) self.schedule_select.setDateTime(QDateTime.currentDateTime()) self.schedule_select.setEnabled(False) self.user_activity_label = QLabel(self) self.user_activity_label.setText("User activity") self.user_activity_combo = QComboBox(self) self.user_activity_combo.addItems([ "0 - Disabled", "1 - Low", "2 - Normal", "3 - Medium", "4 - High", "5 - Very high" ]) self.widget_layout.addRow(self.time_label, None) self.widget_layout.addRow(self.time_now, None) self.widget_layout.addRow(self.time_schedule, self.schedule_select) self.widget_layout.addRow(self.user_activity_label, self.user_activity_combo) self.time_schedule.toggled.connect(self.on_time_schedule_toggled)
def __init__(self, item, parent_layout): super(DateTimeWidget, self).__init__(item, parent_layout) self.dateedit = self.group = QDateTimeEdit() self.dateedit.setCalendarPopup(True) self.dateedit.setToolTip(item.get_help())
def setup(self): for label, value in self.data: if DEBUG_FORMLAYOUT: print("value:", value) # trex: test-skip if label is None and value is None: # Separator: (None, None) self.formlayout.addRow(QLabel(" "), QLabel(" ")) self.widgets.append(None) continue elif label is None: # Comment self.formlayout.addRow(QLabel(value)) self.widgets.append(None) continue elif tuple_to_qfont(value) is not None: field = FontLayout(value, self) elif text_to_qcolor(value).isValid(): field = ColorLayout(QColor(value), self) elif is_text_string(value): if '\n' in value: for linesep in (os.linesep, '\n'): if linesep in value: value = value.replace(linesep, u"\u2029") field = QTextEdit(value, self) else: field = QLineEdit(value, self) elif isinstance(value, (list, tuple)): value = list(value) # in case this is a tuple selindex = value.pop(0) field = QComboBox(self) if isinstance(value[0], (list, tuple)): keys = [key for key, _val in value] value = [val for _key, val in value] else: keys = value field.addItems(value) if selindex in value: selindex = value.index(selindex) elif selindex in keys: selindex = keys.index(selindex) elif not isinstance(selindex, int): print("Warning: '%s' index is invalid (label: "\ "%s, value: %s)" % (selindex, label, value), file=STDERR) selindex = 0 field.setCurrentIndex(selindex) elif isinstance(value, bool): field = QCheckBox(self) field.setCheckState(Qt.Checked if value else Qt.Unchecked) elif isinstance(value, float): field = QLineEdit(repr(value), self) field.setValidator(QDoubleValidator(field)) dialog = self.get_dialog() dialog.register_float_field(field) field.textChanged.connect(lambda text: dialog.update_buttons()) elif isinstance(value, int): field = QSpinBox(self) field.setRange(-1e9, 1e9) field.setValue(value) elif isinstance(value, datetime.datetime): field = QDateTimeEdit(self) field.setDateTime(value) elif isinstance(value, datetime.date): field = QDateEdit(self) field.setDate(value) else: field = QLineEdit(repr(value), self) self.formlayout.addRow(label, field) self.widgets.append(field)
def __init__(self, model, *args, **kwargs): self.model = model super().__init__(*args, **kwargs) self.setLayout(QFormLayout()) # Radiobuttons to quickly select default time period self.all_widget = QRadioButton("All") self.year_widget = QRadioButton("1 Year") self.month_widget = QRadioButton("30 Days") self.week_widget = QRadioButton("1 Week") self.today_widget = QRadioButton("24h") self.hour_widget = QRadioButton("1 Hour") self.radio_button_group = QButtonGroup() self.radio_button_group.addButton(self.all_widget) self.radio_button_group.addButton(self.year_widget) self.radio_button_group.addButton(self.month_widget) self.radio_button_group.addButton(self.week_widget) self.radio_button_group.addButton(self.today_widget) self.radio_button_group.addButton(self.hour_widget) default_period_layout = QGridLayout() default_period_layout.setHorizontalSpacing(85) default_period_layout.setVerticalSpacing(10) default_period_layout.addWidget(self.all_widget, 0, 0, 1, 2) default_period_layout.addWidget(self.year_widget, 1, 0, 1, 2) default_period_layout.addWidget(self.month_widget, 2, 0, 1, 2) default_period_layout.addWidget(self.week_widget, 0, 1, 1, 2) default_period_layout.addWidget(self.today_widget, 1, 1, 1, 2) default_period_layout.addWidget(self.hour_widget, 2, 1, 1, 2) self.layout().addRow("When:", default_period_layout) # TODO: rethink if restriction to acceptable timedelta values is required # from ..models.search.search_input import SearchInput # self.allowed = {timedelta(days=-1), timedelta(days=-30), timedelta(minutes=-60), timedelta(days=-7), # timedelta(days=-365)} # def time_validator(since=None, until=None): # """ # Enforce that since and until are values that a UI can represent. # This is an example similar to what will be used in the Qt UI. # """ # now = timedelta() # if isinstance(since, timedelta): # if not (until is None or until == now): # raise ValueError( # "This UI cannot express since=timedelta(...) unless until " # "is timedelta() or None." # ) # for item in allowed: # if since == item: # break # else: # # No matches # raise ValueError( # "This UI can only express since as a timedelta if it is " # f"one of {allowed}. The value {since} is not allowed" # ) # s = SearchInput() # s.time_validator = time_validator # "Since: <datetime picker>" self.since_widget = QDateTimeEdit() self.since_widget.setCalendarPopup(True) self.since_widget.setDisplayFormat("yyyy-MM-dd HH:mm") self.layout().addRow("Since:", self.since_widget) # "Until: <datetime picker>" self.until_widget = QDateTimeEdit() self.until_widget.setCalendarPopup(True) self.until_widget.setDisplayFormat("yyyy-MM-dd HH:mm") self.layout().addRow("Until:", self.until_widget) # Refresh Button self.refresh_button = QPushButton("Refresh") self.layout().addWidget(self.refresh_button) # Changes to the GUI update the model. self.since_widget.dateTimeChanged.connect(self.on_since_view_changed) self.until_widget.dateTimeChanged.connect(self.on_until_view_changed) self.refresh_button.clicked.connect(self.model.request_reload) self.model.events.reload.connect(self.on_reload) self.model.events.query.connect(self.on_reload) # Changes to the model update the GUI. self.model.events.since.connect(self.on_since_model_changed) self.model.events.until.connect(self.on_until_model_changed) # connect QRadioButtons and change date dropdowns (since/until widgets) accordingly self.hour_widget.toggled.connect(self.on_toggle_hour) self.today_widget.toggled.connect(self.on_toggle_24h) self.week_widget.toggled.connect(self.on_toggle_week) self.month_widget.toggled.connect(self.on_toggle_month) self.year_widget.toggled.connect(self.on_toggle_year) self.all_widget.toggled.connect(self.on_toggle_all) self.all_widget.setChecked(True)
class QtSearchInput(QWidget): """ Qt view for SearchInput Parameters ---------- model: SearchInput """ def __init__(self, model, *args, **kwargs): self.model = model super().__init__(*args, **kwargs) self.setLayout(QFormLayout()) # Radiobuttons to quickly select default time period self.all_widget = QRadioButton("All") self.year_widget = QRadioButton("1 Year") self.month_widget = QRadioButton("30 Days") self.week_widget = QRadioButton("1 Week") self.today_widget = QRadioButton("24h") self.hour_widget = QRadioButton("1 Hour") self.radio_button_group = QButtonGroup() self.radio_button_group.addButton(self.all_widget) self.radio_button_group.addButton(self.year_widget) self.radio_button_group.addButton(self.month_widget) self.radio_button_group.addButton(self.week_widget) self.radio_button_group.addButton(self.today_widget) self.radio_button_group.addButton(self.hour_widget) default_period_layout = QGridLayout() default_period_layout.setHorizontalSpacing(85) default_period_layout.setVerticalSpacing(10) default_period_layout.addWidget(self.all_widget, 0, 0, 1, 2) default_period_layout.addWidget(self.year_widget, 1, 0, 1, 2) default_period_layout.addWidget(self.month_widget, 2, 0, 1, 2) default_period_layout.addWidget(self.week_widget, 0, 1, 1, 2) default_period_layout.addWidget(self.today_widget, 1, 1, 1, 2) default_period_layout.addWidget(self.hour_widget, 2, 1, 1, 2) self.layout().addRow("When:", default_period_layout) # TODO: rethink if restriction to acceptable timedelta values is required # from ..models.search.search_input import SearchInput # self.allowed = {timedelta(days=-1), timedelta(days=-30), timedelta(minutes=-60), timedelta(days=-7), # timedelta(days=-365)} # def time_validator(since=None, until=None): # """ # Enforce that since and until are values that a UI can represent. # This is an example similar to what will be used in the Qt UI. # """ # now = timedelta() # if isinstance(since, timedelta): # if not (until is None or until == now): # raise ValueError( # "This UI cannot express since=timedelta(...) unless until " # "is timedelta() or None." # ) # for item in allowed: # if since == item: # break # else: # # No matches # raise ValueError( # "This UI can only express since as a timedelta if it is " # f"one of {allowed}. The value {since} is not allowed" # ) # s = SearchInput() # s.time_validator = time_validator # "Since: <datetime picker>" self.since_widget = QDateTimeEdit() self.since_widget.setCalendarPopup(True) self.since_widget.setDisplayFormat("yyyy-MM-dd HH:mm") self.layout().addRow("Since:", self.since_widget) # "Until: <datetime picker>" self.until_widget = QDateTimeEdit() self.until_widget.setCalendarPopup(True) self.until_widget.setDisplayFormat("yyyy-MM-dd HH:mm") self.layout().addRow("Until:", self.until_widget) # Refresh Button self.refresh_button = QPushButton("Refresh") self.layout().addWidget(self.refresh_button) # Changes to the GUI update the model. self.since_widget.dateTimeChanged.connect(self.on_since_view_changed) self.until_widget.dateTimeChanged.connect(self.on_until_view_changed) self.refresh_button.clicked.connect(self.model.request_reload) self.model.events.reload.connect(self.on_reload) self.model.events.query.connect(self.on_reload) # Changes to the model update the GUI. self.model.events.since.connect(self.on_since_model_changed) self.model.events.until.connect(self.on_until_model_changed) # connect QRadioButtons and change date dropdowns (since/until widgets) accordingly self.hour_widget.toggled.connect(self.on_toggle_hour) self.today_widget.toggled.connect(self.on_toggle_24h) self.week_widget.toggled.connect(self.on_toggle_week) self.month_widget.toggled.connect(self.on_toggle_month) self.year_widget.toggled.connect(self.on_toggle_year) self.all_widget.toggled.connect(self.on_toggle_all) self.all_widget.setChecked(True) def on_reload(self, event): now = datetime.now(LOCAL_TIMEZONE) if isinstance(self.model.since, timedelta): with _blocked(self.since_widget): self.since_widget.setDateTime(as_qdatetime(now + self.model.since)) if isinstance(self.model.until, timedelta): with _blocked(self.until_widget): self.until_widget.setDateTime(as_qdatetime(now + self.model.until)) def on_since_view_changed(self, qdatetime): # When GUI is updated self.model.since = QDateTime.toPython(qdatetime) def on_since_model_changed(self, event): # When model is updated (e.g. from console or by clicking a QRadioButton) now = datetime.now(LOCAL_TIMEZONE) if isinstance(event.date, timedelta): qdatetime = as_qdatetime(now + event.date) if event.date == timedelta(minutes=-60): self.hour_widget.setChecked(True) elif event.date == timedelta(days=-1): self.today_widget.setChecked(True) elif event.date == timedelta(days=-7): self.week_widget.setChecked(True) elif event.date == timedelta(days=-30): self.month_widget.setChecked(True) elif event.date == timedelta(days=-365): self.year_widget.setChecked(True) else: # No checkbox associated with this custom timedelta pass else: # Must be a datetime if event.date == ADA_LOVELACE_BIRTHDAY: self.all_widget.setChecked(True) else: self.uncheck_radiobuttons() qdatetime = as_qdatetime(event.date) with _blocked(self.since_widget): self.since_widget.setDateTime(qdatetime) with _blocked(self.until_widget): self.until_widget.setDateTime(as_qdatetime(now)) def on_until_view_changed(self, qdatetime): # When GUI is updated self.model.until = QDateTime.toPython(qdatetime) def on_until_model_changed(self, event): # When model is updated (e.g. from console or by clicking a QRadioButton) if not isinstance(event.date, timedelta): qdatetime = as_qdatetime(event.date) self.uncheck_radiobuttons() with _blocked(self.until_widget): self.until_widget.setDateTime(qdatetime) def on_toggle_24h(self): if self.today_widget.isChecked(): self.model.since = timedelta(days=-1) self.model.until = timedelta() def on_toggle_hour(self): if self.hour_widget.isChecked(): self.model.since = timedelta(minutes=-60) self.model.until = timedelta() def on_toggle_week(self): if self.week_widget.isChecked(): self.model.since = timedelta(days=-7) self.model.until = timedelta() def on_toggle_month(self): if self.month_widget.isChecked(): self.model.since = timedelta(days=-30) self.model.until = timedelta() def on_toggle_year(self): if self.year_widget.isChecked(): self.model.since = timedelta(days=-365) self.model.until = timedelta() def on_toggle_all(self): # Search for all catalogs since Ada Lovelace's Birthday. if self.all_widget.isChecked(): self.model.since = ADA_LOVELACE_BIRTHDAY self.model.until = timedelta() def uncheck_radiobuttons(self): self.radio_button_group.setExclusive(False) self.all_widget.setChecked(False) self.year_widget.setChecked(False) self.month_widget.setChecked(False) self.week_widget.setChecked(False) self.today_widget.setChecked(False) self.hour_widget.setChecked(False) self.radio_button_group.setExclusive(True)
def createEditor(self, parent, option, index, object_explorer=False): """Overriding method createEditor""" val_type = index.sibling(index.row(), 1).data() self.sig_editor_creation_started.emit() if index.column() < 3: return None if self.show_warning(index): answer = QMessageBox.warning( self.parent(), _("Warning"), _("Opening this variable can be slow\n\n" "Do you want to continue anyway?"), QMessageBox.Yes | QMessageBox.No) if answer == QMessageBox.No: self.sig_editor_shown.emit() return None try: value = self.get_value(index) if value is None: return None except ImportError as msg: self.sig_editor_shown.emit() module = str(msg).split("'")[1] if module in ['pandas', 'numpy']: if module == 'numpy': val_type = 'array' else: val_type = 'dataframe, series' message = _("Spyder is unable to show the {val_type} or object" " you're trying to view because <tt>{module}</tt>" " is not installed. ") if running_in_mac_app(): message += _("Please consider using the full version of " "the Spyder MacOS application.<br>") else: message += _("Please install this package in your Spyder " "environment.<br>") QMessageBox.critical( self.parent(), _("Error"), message.format(val_type=val_type, module=module)) return else: if running_in_mac_app() or is_pynsist(): message = _("Spyder is unable to show the variable you're" " trying to view because the module " "<tt>{module}</tt> is not supported in the " "Spyder Lite application.<br>") else: message = _("Spyder is unable to show the variable you're" " trying to view because the module " "<tt>{module}</tt> is not found in your " "Spyder environment. Please install this " "package in this environment.<br>") QMessageBox.critical(self.parent(), _("Error"), message.format(module=module)) return except Exception as msg: QMessageBox.critical( self.parent(), _("Error"), _("Spyder was unable to retrieve the value of " "this variable from the console.<br><br>" "The error message was:<br>" "%s") % to_text_string(msg)) return key = index.model().get_key(index) readonly = (isinstance(value, (tuple, set)) or self.parent().readonly or not is_known_type(value)) # We can't edit Numpy void objects because they could be anything, so # this might cause a crash. # Fixes spyder-ide/spyder#10603 if isinstance(value, np.void): self.sig_editor_shown.emit() return None # CollectionsEditor for a list, tuple, dict, etc. elif isinstance(value, (list, set, tuple, dict)) and not object_explorer: from spyder.widgets.collectionseditor import CollectionsEditor editor = CollectionsEditor(parent=parent) editor.setup(value, key, icon=self.parent().windowIcon(), readonly=readonly) self.create_dialog(editor, dict(model=index.model(), editor=editor, key=key, readonly=readonly)) return None # ArrayEditor for a Numpy array elif (isinstance(value, (np.ndarray, np.ma.MaskedArray)) and np.ndarray is not FakeObject and not object_explorer): # We need to leave this import here for tests to pass. from .arrayeditor import ArrayEditor editor = ArrayEditor(parent=parent) if not editor.setup_and_check(value, title=key, readonly=readonly): return self.create_dialog(editor, dict(model=index.model(), editor=editor, key=key, readonly=readonly)) return None # ArrayEditor for an images elif (isinstance(value, PIL.Image.Image) and np.ndarray is not FakeObject and PIL.Image is not FakeObject and not object_explorer): # Sometimes the ArrayEditor import above is not seen (don't know # why), so we need to reimport it here. # Fixes spyder-ide/spyder#16731 from .arrayeditor import ArrayEditor arr = np.array(value) editor = ArrayEditor(parent=parent) if not editor.setup_and_check(arr, title=key, readonly=readonly): return conv_func = lambda arr: PIL.Image.fromarray(arr, mode=value.mode) self.create_dialog(editor, dict(model=index.model(), editor=editor, key=key, readonly=readonly, conv=conv_func)) return None # DataFrameEditor for a pandas dataframe, series or index elif (isinstance(value, (pd.DataFrame, pd.Index, pd.Series)) and pd.DataFrame is not FakeObject and not object_explorer): # We need to leave this import here for tests to pass. from .dataframeeditor import DataFrameEditor editor = DataFrameEditor(parent=parent) if not editor.setup_and_check(value, title=key): self.sig_editor_shown.emit() return self.create_dialog(editor, dict(model=index.model(), editor=editor, key=key, readonly=readonly)) return None # QDateEdit and QDateTimeEdit for a dates or datetime respectively elif isinstance(value, datetime.date) and not object_explorer: if readonly: self.sig_editor_shown.emit() return None else: if isinstance(value, datetime.datetime): editor = QDateTimeEdit(value, parent=parent) # Needed to handle NaT values # See spyder-ide/spyder#8329 try: value.time() except ValueError: self.sig_editor_shown.emit() return None else: editor = QDateEdit(value, parent=parent) editor.setCalendarPopup(True) editor.setFont(get_font(font_size_delta=DEFAULT_SMALL_DELTA)) self.sig_editor_shown.emit() return editor # TextEditor for a long string elif is_text_string(value) and len(value) > 40 and not object_explorer: te = TextEditor(None, parent=parent) if te.setup_and_check(value): editor = TextEditor(value, key, readonly=readonly, parent=parent) self.create_dialog(editor, dict(model=index.model(), editor=editor, key=key, readonly=readonly)) return None # QLineEdit for an individual value (int, float, short string, etc) elif is_editable_type(value) and not object_explorer: if readonly: self.sig_editor_shown.emit() return None else: editor = QLineEdit(parent=parent) editor.setFont(get_font(font_size_delta=DEFAULT_SMALL_DELTA)) editor.setAlignment(Qt.AlignLeft) # This is making Spyder crash because the QLineEdit that it's # been modified is removed and a new one is created after # evaluation. So the object on which this method is trying to # act doesn't exist anymore. # editor.returnPressed.connect(self.commitAndCloseEditor) self.sig_editor_shown.emit() return editor # ObjectExplorer for an arbitrary Python object else: from spyder.plugins.variableexplorer.widgets.objectexplorer \ import ObjectExplorer editor = ObjectExplorer( value, name=key, parent=parent, readonly=readonly) self.create_dialog(editor, dict(model=index.model(), editor=editor, key=key, readonly=readonly)) return None
class QtSearchInput(QWidget): """ Qt view for SearchInput Parameters ---------- model: SearchInput """ def __init__(self, model, *args, **kwargs): self.model = model super().__init__(*args, **kwargs) # "Since: <datetime picker>" self.since_widget = QDateTimeEdit() self.since_widget.setCalendarPopup(True) self.since_widget.setDisplayFormat("yyyy-MM-dd HH:mm") since_layout = QHBoxLayout() since_layout.addWidget(QLabel("Since:")) since_layout.addWidget(self.since_widget) since_layout_widget = QWidget() since_layout_widget.setLayout(since_layout) # "Until: <datetime picker>" self.until_widget = QDateTimeEdit() self.until_widget.setCalendarPopup(True) self.until_widget.setDisplayFormat("yyyy-MM-dd HH:mm") until_layout = QHBoxLayout() until_layout.addWidget(QLabel("Until:")) until_layout.addWidget(self.until_widget) until_layout_widget = QWidget() until_layout_widget.setLayout(until_layout) self.refresh_button = QPushButton("Refresh") # Stack them up. layout = QVBoxLayout() layout.addWidget(since_layout_widget) layout.addWidget(until_layout_widget) layout.addWidget(self.refresh_button) self.setLayout(layout) # Initialize values. qdatetime = QDateTime() qdatetime.setSecsSinceEpoch(self.model.since) self.since_widget.setDateTime(qdatetime) qdatetime = QDateTime() qdatetime.setSecsSinceEpoch(self.model.until) self.until_widget.setDateTime(qdatetime) # Changes to the GUI update the model. self.since_widget.dateTimeChanged.connect(self.on_since_view_changed) self.until_widget.dateTimeChanged.connect(self.on_until_view_changed) self.refresh_button.clicked.connect(self.model.events.reload) # Changes to the model update the GUI. self.model.events.since.connect(self.on_since_model_changed) self.model.events.until.connect(self.on_until_model_changed) def on_since_view_changed(self, qdatetime): # When GUI is updated self.model.since = qdatetime.toSecsSinceEpoch() def on_since_model_changed(self, event): # When model is updated (e.g. from console) qdatetime = QDateTime() qdatetime.setSecsSinceEpoch(event.date) self.since_widget.setDateTime(qdatetime) def on_until_view_changed(self, qdatetime): # When GUI is updated self.model.until = qdatetime.toSecsSinceEpoch() def on_until_model_changed(self, event): # When model is updated (e.g. from console) qdatetime = QDateTime() qdatetime.setSecsSinceEpoch(event.date) self.until_widget.setDateTime(qdatetime)
def createEditor(self, parent, option, index): """Overriding method createEditor""" if self.show_warning(index): answer = QMessageBox.warning( self.parent(), _("Warning"), _("Opening this variable can be slow\n\n" "Do you want to continue anyway?"), QMessageBox.Yes | QMessageBox.No) if answer == QMessageBox.No: return None try: value = self.get_value(index) try: self.old_obj = value.copy() except AttributeError: self.old_obj = copy.deepcopy(value) if value is None: return None except Exception as msg: QMessageBox.critical( self.parent(), _("Error"), _("Spyder was unable to retrieve the value of " "this variable from the console.<br><br>" "The error message was:<br>" "<i>%s</i>") % to_text_string(msg)) return self.current_index = index key = index.model().get_key(index).obj_name readonly = (isinstance(value, (tuple, set)) or self.parent().readonly or not is_known_type(value)) # CollectionsEditor for a list, tuple, dict, etc. if isinstance(value, (list, set, tuple, dict)): from spyder.widgets.collectionseditor import CollectionsEditor editor = CollectionsEditor(parent=parent) editor.setup(value, key, icon=self.parent().windowIcon(), readonly=readonly) self.create_dialog( editor, dict(model=index.model(), editor=editor, key=key, readonly=readonly)) return None # ArrayEditor for a Numpy array elif (isinstance(value, (ndarray, MaskedArray)) and ndarray is not FakeObject): editor = ArrayEditor(parent=parent) if not editor.setup_and_check(value, title=key, readonly=readonly): return self.create_dialog( editor, dict(model=index.model(), editor=editor, key=key, readonly=readonly)) return None # ArrayEditor for an images elif (isinstance(value, Image) and ndarray is not FakeObject and Image is not FakeObject): arr = array(value) editor = ArrayEditor(parent=parent) if not editor.setup_and_check(arr, title=key, readonly=readonly): return conv_func = lambda arr: Image.fromarray(arr, mode=value.mode) self.create_dialog( editor, dict(model=index.model(), editor=editor, key=key, readonly=readonly, conv=conv_func)) return None # DataFrameEditor for a pandas dataframe, series or index elif (isinstance(value, (DataFrame, Index, Series)) and DataFrame is not FakeObject): editor = DataFrameEditor(parent=parent) if not editor.setup_and_check(value, title=key): return editor.dataModel.set_format(index.model().dataframe_format) editor.sig_option_changed.connect(self.change_option) self.create_dialog( editor, dict(model=index.model(), editor=editor, key=key, readonly=readonly)) return None # QDateEdit and QDateTimeEdit for a dates or datetime respectively elif isinstance(value, datetime.date): if readonly: return None else: if isinstance(value, datetime.datetime): editor = QDateTimeEdit(value, parent=parent) else: editor = QDateEdit(value, parent=parent) editor.setCalendarPopup(True) editor.setFont(get_font(font_size_delta=DEFAULT_SMALL_DELTA)) return editor # TextEditor for a long string elif is_text_string(value) and len(value) > 40: te = TextEditor(None, parent=parent) if te.setup_and_check(value): editor = TextEditor(value, key, readonly=readonly, parent=parent) self.create_dialog( editor, dict(model=index.model(), editor=editor, key=key, readonly=readonly)) return None # QLineEdit for an individual value (int, float, short string, etc) elif is_editable_type(value): if readonly: return None else: editor = QLineEdit(parent=parent) editor.setFont(get_font(font_size_delta=DEFAULT_SMALL_DELTA)) editor.setAlignment(Qt.AlignLeft) # This is making Spyder crash because the QLineEdit that it's # been modified is removed and a new one is created after # evaluation. So the object on which this method is trying to # act doesn't exist anymore. # editor.returnPressed.connect(self.commitAndCloseEditor) return editor # An arbitrary Python object. # Since we are already in the Object Explorer no editor is needed else: return None
def createEditor(self, parent, option, index, object_explorer=False): """Overriding method createEditor""" val_type = index.sibling(index.row(), 1).data() self.sig_open_editor.emit() if index.column() < 3: return None if self.show_warning(index): answer = QMessageBox.warning( self.parent(), _("Warning"), _("Opening this variable can be slow\n\n" "Do you want to continue anyway?"), QMessageBox.Yes | QMessageBox.No) if answer == QMessageBox.No: return None try: value = self.get_value(index) if value is None: return None except ImportError as msg: self.sig_editor_shown.emit() module = str(msg).split("'")[1] if module in ['pandas', 'numpy']: if module == 'numpy': val_type = 'array' else: val_type = 'dataframe, series' QMessageBox.critical( self.parent(), _("Error"), _("Spyder is unable to show the {val_type} or object " "you're trying to view because <tt>{module}</tt> was " "not installed alongside Spyder. Please install " "this package in your Spyder environment." "<br>").format(val_type=val_type, module=module)) return else: QMessageBox.critical( self.parent(), _("Error"), _("Spyder is unable to show the variable you're " "trying to view because the module " "<tt>{module}</tt> was not found in your " "Spyder environment. Please install " "this package in your Spyder environment." "<br>").format(module=module)) return except Exception as msg: QMessageBox.critical( self.parent(), _("Error"), _("Spyder was unable to retrieve the value of " "this variable from the console.<br><br>" "The error message was:<br>" "%s") % to_text_string(msg)) return key = index.model().get_key(index) readonly = (isinstance(value, (tuple, set)) or self.parent().readonly or not is_known_type(value)) # CollectionsEditor for a list, tuple, dict, etc. if isinstance(value, (list, set, tuple, dict)) and not object_explorer: from spyder.widgets.collectionseditor import CollectionsEditor editor = CollectionsEditor(parent=parent) editor.setup(value, key, icon=self.parent().windowIcon(), readonly=readonly) self.create_dialog( editor, dict(model=index.model(), editor=editor, key=key, readonly=readonly)) return None # ArrayEditor for a Numpy array elif (isinstance(value, (ndarray, MaskedArray)) and ndarray is not FakeObject and not object_explorer): editor = ArrayEditor(parent=parent) if not editor.setup_and_check(value, title=key, readonly=readonly): return self.create_dialog( editor, dict(model=index.model(), editor=editor, key=key, readonly=readonly)) return None # ArrayEditor for an images elif (isinstance(value, Image) and ndarray is not FakeObject and Image is not FakeObject and not object_explorer): arr = array(value) editor = ArrayEditor(parent=parent) if not editor.setup_and_check(arr, title=key, readonly=readonly): return conv_func = lambda arr: Image.fromarray(arr, mode=value.mode) self.create_dialog( editor, dict(model=index.model(), editor=editor, key=key, readonly=readonly, conv=conv_func)) return None # DataFrameEditor for a pandas dataframe, series or index elif (isinstance(value, (DataFrame, Index, Series)) and DataFrame is not FakeObject and not object_explorer): editor = DataFrameEditor(parent=parent) if not editor.setup_and_check(value, title=key): return editor.dataModel.set_format(index.model().dataframe_format) editor.sig_option_changed.connect(self.change_option) self.create_dialog( editor, dict(model=index.model(), editor=editor, key=key, readonly=readonly)) return None # QDateEdit and QDateTimeEdit for a dates or datetime respectively elif isinstance(value, datetime.date) and not object_explorer: # Needed to handle NaT values # See spyder-ide/spyder#8329 try: value.time() except ValueError: self.sig_editor_shown.emit() return None if readonly: self.sig_editor_shown.emit() return None else: if isinstance(value, datetime.datetime): editor = QDateTimeEdit(value, parent=parent) else: editor = QDateEdit(value, parent=parent) editor.setCalendarPopup(True) editor.setFont(get_font(font_size_delta=DEFAULT_SMALL_DELTA)) self.sig_editor_shown.emit() return editor # TextEditor for a long string elif is_text_string(value) and len(value) > 40 and not object_explorer: te = TextEditor(None, parent=parent) if te.setup_and_check(value): editor = TextEditor(value, key, readonly=readonly, parent=parent) self.create_dialog( editor, dict(model=index.model(), editor=editor, key=key, readonly=readonly)) return None # QLineEdit for an individual value (int, float, short string, etc) elif is_editable_type(value) and not object_explorer: if readonly: self.sig_editor_shown.emit() return None else: editor = QLineEdit(parent=parent) editor.setFont(get_font(font_size_delta=DEFAULT_SMALL_DELTA)) editor.setAlignment(Qt.AlignLeft) # This is making Spyder crash because the QLineEdit that it's # been modified is removed and a new one is created after # evaluation. So the object on which this method is trying to # act doesn't exist anymore. # editor.returnPressed.connect(self.commitAndCloseEditor) self.sig_editor_shown.emit() return editor # ObjectExplorer for an arbitrary Python object else: show_callable_attributes = index.model().show_callable_attributes show_special_attributes = index.model().show_special_attributes dataframe_format = index.model().dataframe_format if show_callable_attributes is None: show_callable_attributes = False if show_special_attributes is None: show_special_attributes = False from spyder.plugins.variableexplorer.widgets.objectexplorer \ import ObjectExplorer editor = ObjectExplorer( value, name=key, parent=parent, show_callable_attributes=show_callable_attributes, show_special_attributes=show_special_attributes, dataframe_format=dataframe_format, readonly=readonly) editor.sig_option_changed.connect(self.change_option) self.create_dialog( editor, dict(model=index.model(), editor=editor, key=key, readonly=readonly)) return None
class MacReportWindow(SiriusMainWindow): """Machine Report Window.""" def __init__(self, parent=None): """Init.""" super().__init__(parent) self._macreport = MacReport() self._macreport.connector.timeout = 5 * 60 self.setWindowIcon(qta.icon('fa.book', color='gray')) self.setWindowTitle('Machine Reports') self._fsi = '{:8d}' self._fs1 = '{:8.3f}' self._fs2 = '{:8.3f} ± {:8.3f}' self._fst1 = '{:02d}h{:02d}' self._fst2 = '{:02d}h{:02d} ± {:02d}h{:02d}' self._update_task = None self._setupUi() self.setFocusPolicy(Qt.StrongFocus) self.setFocus(True) def _setupUi(self): cwid = QWidget(self) self.setCentralWidget(cwid) title = QLabel('<h3>Machine Reports</h3>', self, alignment=Qt.AlignCenter) self._timesel_gbox = self._setupTimePeriodSelWidget() self._timesel_gbox.setObjectName('timesel_gbox') self._timesel_gbox.setStyleSheet( "#timesel_gbox{min-height: 8em; max-height: 8em;}") self._progress_list = QListWidget(self) self._progress_list.setObjectName('progress_list') self._progress_list.setStyleSheet( "#progress_list{min-height: 8em; max-height: 8em;}") self._reports_wid = QTabWidget(cwid) self._reports_wid.setObjectName('ASTab') self._reports_wid.addTab(self._setupUserShiftStatsWidget(), 'User Shift Stats') self._reports_wid.addTab(self._setupLightSourceUsageStats(), 'Light Source Usage Stats') self._reports_wid.addTab(self._setupStoredCurrentStats(), 'Stored Current Stats') self._pb_showraw = QPushButton(qta.icon('mdi.chart-line'), 'Show Raw Data', self) self._pb_showraw.setEnabled(False) self._pb_showraw.clicked.connect(self._show_raw_data) self._pb_showpvsd = QPushButton(qta.icon('mdi.chart-line'), 'Show Progrmd.vs.Delivered Hours', self) self._pb_showpvsd.setEnabled(False) self._pb_showpvsd.clicked.connect(self._show_progmd_vs_delivd) lay = QGridLayout(cwid) lay.setVerticalSpacing(10) lay.setHorizontalSpacing(10) lay.setContentsMargins(18, 9, 18, 9) lay.addWidget(title, 0, 0, 1, 3) lay.addWidget(self._timesel_gbox, 1, 0) lay.addWidget(self._progress_list, 1, 1, 1, 2, alignment=Qt.AlignBottom) lay.addWidget(self._reports_wid, 2, 0, 1, 3) lay.addWidget(self._pb_showpvsd, 4, 0, alignment=Qt.AlignLeft) lay.addWidget(self._pb_showraw, 4, 2, alignment=Qt.AlignRight) self._updateUserShiftStats(setup=True) self._updateStoredCurrentStats(setup=True) self._updateLightSourceUsageStats(setup=True) def _setupTimePeriodSelWidget(self): tnow = Time.now() ld_tstart = QLabel('Time start: ') self.dt_start = QDateTimeEdit(tnow - 10 * 60, self) self.dt_start.setCalendarPopup(True) self.dt_start.setMinimumDate(Time(2020, 1, 1)) self.dt_start.setDisplayFormat('dd/MM/yyyy hh:mm') ld_tstop = QLabel('Time stop: ') self.dt_stop = QDateTimeEdit(tnow, self) self.dt_stop.setCalendarPopup(True) self.dt_stop.setMinimumDate(Time(2020, 1, 1)) self.dt_stop.setDisplayFormat('dd/MM/yyyy hh:mm') self.pb_search = QPushButton(qta.icon('fa5s.search'), 'Search', self) self.pb_search.clicked.connect(self._do_update) self.pb_search.setObjectName('pb_search') self.pb_search.setStyleSheet(""" #pb_search{ min-width:100px; max-width:100px; min-height:25px; max-height:25px; icon-size:20px;} """) wid = QGroupBox('Select interval: ', self) lay = QGridLayout(wid) lay.addWidget(ld_tstart, 0, 0) lay.addWidget(self.dt_start, 0, 1) lay.addWidget(ld_tstop, 1, 0) lay.addWidget(self.dt_stop, 1, 1) lay.addWidget(self.pb_search, 2, 1, alignment=Qt.AlignRight) return wid def _setupUserShiftStatsWidget(self): self.lb_uspt = LbData('') self.lb_usdt = LbData('') self.lb_ustt = LbData('') self.lb_uset = LbData('') self.lb_uspc = LbData('') self.lb_cav = LbData('') self.lb_cbav = LbData('') self.lb_ceav = LbData('') self.lb_tft = LbData('') self.lb_bdc = LbData('') self.lb_mttr = LbData('') self.lb_mtbf = LbData('') self.lb_reli = LbData('') self.lb_tsbt = LbData('') self.lb_tubt = LbData('') self.lb_mtbu = LbData('') self.lb_rsbt = LbData('') self.lb_itav = LbData('') wid = QWidget(self) lay = QGridLayout(wid) lay.setVerticalSpacing(0) lay.setHorizontalSpacing(0) lay.setAlignment(Qt.AlignTop) lay.addItem(QSpacerItem(120, 1, QSzPlcy.Fixed, QSzPlcy.Ignored), 0, 0) lay.addWidget(LbHHeader('Programmed Time (h)'), 0, 1) lay.addWidget(self.lb_uspt, 0, 2) lay.addWidget(LbHHeader('Delivered Time (h)'), 1, 1) lay.addWidget(self.lb_usdt, 1, 2) lay.addWidget(LbHHeader('Total Time (h)'), 2, 1) lay.addWidget(self.lb_ustt, 2, 2) lay.addWidget(LbHHeader('Extra Time (h)'), 3, 1) lay.addWidget(self.lb_uset, 3, 2) lay.addWidget(LbHHeader('# Programmed Shifts'), 4, 1) lay.addWidget(self.lb_uspc, 4, 2) lay.addWidget(LbHHeader('Current (avg ± std) (mA)'), 5, 1) lay.addWidget(self.lb_cav, 5, 2) lay.addWidget( LbHHeader('Current at the Beg. of the Shift (avg ± std) (mA)'), 6, 1) lay.addWidget(self.lb_cbav, 6, 2) lay.addWidget( LbHHeader('Current at the End of the Shift (avg ± std) (mA)'), 7, 1) lay.addWidget(self.lb_ceav, 7, 2) lay.addWidget(LbHHeader('Total Failures Time (h)'), 8, 1) lay.addWidget(self.lb_tft, 8, 2) lay.addWidget(LbHHeader('# Beam Dumps'), 9, 1) lay.addWidget(self.lb_bdc, 9, 2) lay.addWidget(LbHHeader('Time To Recover (avg ± std) (h)'), 10, 1) lay.addWidget(self.lb_mttr, 10, 2) lay.addWidget(LbHHeader('Time Between Failures (avg) (h)'), 11, 1) lay.addWidget(self.lb_mtbf, 11, 2) lay.addWidget(LbHHeader('Beam Reliability (%)'), 12, 1) lay.addWidget(self.lb_reli, 12, 2) lay.addWidget(LbHHeader('Total stable beam time (h)'), 13, 1) lay.addWidget(self.lb_tsbt, 13, 2) lay.addWidget(LbHHeader('Total unstable beam time (h)'), 14, 1) lay.addWidget(self.lb_tubt, 14, 2) lay.addWidget(LbHHeader('Time between unstable beams (avg) (h)'), 15, 1) lay.addWidget(self.lb_mtbu, 15, 2) lay.addWidget(LbHHeader('Relative stable beam time (%)'), 16, 1) lay.addWidget(self.lb_rsbt, 16, 2) lay.addWidget(LbHHeader('Injection time (avg ± std) (h)'), 17, 1) lay.addWidget(self.lb_itav, 17, 2) lay.addItem(QSpacerItem(120, 1, QSzPlcy.Fixed, QSzPlcy.Ignored), 0, 3) return wid def _updateUserShiftStats(self, setup=False): w2r = { 'uspt': [ 'usershift_progmd_time', ], 'usdt': [ 'usershift_delivd_time', ], 'ustt': [ 'usershift_total_time', ], 'uset': [ 'usershift_extra_time', ], 'uspc': [ 'usershift_progmd_count', ], 'cav': ['usershift_current_average', 'usershift_current_stddev'], 'cbav': ['usershift_current_beg_average', 'usershift_current_beg_stddev'], 'ceav': ['usershift_current_end_average', 'usershift_current_end_stddev'], 'tft': [ 'usershift_total_failures_time', ], 'bdc': [ 'usershift_beam_dump_count', ], 'mttr': [ 'usershift_time_to_recover_average', 'usershift_time_to_recover_stddev' ], 'mtbf': [ 'usershift_time_between_failures_average', ], 'reli': [ 'usershift_beam_reliability', ], 'tsbt': [ 'usershift_total_stable_beam_time', ], 'tubt': [ 'usershift_total_unstable_beam_time', ], 'mtbu': ['usershift_time_between_unstable_beams_average'], 'rsbt': ['usershift_relative_stable_beam_time'], 'itav': [ 'usershift_injection_time_average', 'usershift_injection_time_stddev' ] } for wname, rname in w2r.items(): wid = getattr(self, 'lb_' + wname) items = [getattr(self._macreport, n) for n in rname] if 'time' in rname[0] and 'relative' not in rname[0]: if len(items) == 2: if items[0] not in [None, _np.inf]: hour1 = int(items[0]) minu1 = int((items[0] - hour1) * 60) hour2 = int(items[1]) minu2 = int((items[1] - hour2) * 60) items = [hour1, minu1, hour2, minu2] str2fmt = self._fst2 else: str2fmt = self._fs1 elif items[0] not in [None, _np.inf]: hour = int(items[0]) minu = int((items[0] - hour) * 60) items = [hour, minu] str2fmt = self._fst1 else: str2fmt = self._fs1 else: str2fmt = getattr( self, '_fsi' if 'count' in rname[0] else '_fs' + str(len(rname))) text = '' if any([i is None for i in items]) \ else str2fmt.format(*items) wid.setText(text) if setup: wid.setToolTip(getattr(MacReport, rname[0]).__doc__) def _setupStoredCurrentStats(self): self.lb_user_mb_avg = LbData('') self.lb_user_mb_intvl = LbData('') self.lb_user_sb_avg = LbData('') self.lb_user_sb_intvl = LbData('') self.lb_user_tt_avg = LbData('') self.lb_user_tt_intvl = LbData('') self.lb_commi_mb_avg = LbData('') self.lb_commi_mb_intvl = LbData('') self.lb_commi_sb_avg = LbData('') self.lb_commi_sb_intvl = LbData('') self.lb_commi_tt_avg = LbData('') self.lb_commi_tt_intvl = LbData('') self.lb_condi_mb_avg = LbData('') self.lb_condi_mb_intvl = LbData('') self.lb_condi_sb_avg = LbData('') self.lb_condi_sb_intvl = LbData('') self.lb_condi_tt_avg = LbData('') self.lb_condi_tt_intvl = LbData('') self.lb_mstdy_mb_avg = LbData('') self.lb_mstdy_mb_intvl = LbData('') self.lb_mstdy_sb_avg = LbData('') self.lb_mstdy_sb_intvl = LbData('') self.lb_mstdy_tt_avg = LbData('') self.lb_mstdy_tt_intvl = LbData('') self.lb_stord_mb_avg = LbData('') self.lb_stord_mb_intvl = LbData('') self.lb_stord_sb_avg = LbData('') self.lb_stord_sb_intvl = LbData('') self.lb_stord_tt_avg = LbData('') self.lb_stord_tt_intvl = LbData('') wid = QWidget(self) lay = QGridLayout(wid) lay.setVerticalSpacing(0) lay.setHorizontalSpacing(0) lay.setAlignment(Qt.AlignTop) lay.addWidget(LbHHeader('Current (avg ± std) (mA) (MB)'), 1, 0) lay.addWidget(LbHHeader('Time in MB mode (h)'), 2, 0) lay.addWidget(LbHHeader('Current (avg ± std) (mA) (SB)'), 3, 0) lay.addWidget(LbHHeader('Time in SB mode (h)'), 4, 0) lay.addWidget(LbHHeader('Current (avg ± std) (mA) (SB+MB)'), 5, 0) lay.addWidget(LbHHeader('Total Time (h) (SB+MB)'), 6, 0) lay.addWidget(LbVHeader('Users'), 0, 1) lay.addWidget(self.lb_user_mb_avg, 1, 1) lay.addWidget(self.lb_user_mb_intvl, 2, 1) lay.addWidget(self.lb_user_sb_avg, 3, 1) lay.addWidget(self.lb_user_sb_intvl, 4, 1) lay.addWidget(self.lb_user_tt_avg, 5, 1) lay.addWidget(self.lb_user_tt_intvl, 6, 1) lay.addWidget(LbVHeader('Commissioning'), 0, 2) lay.addWidget(self.lb_commi_mb_avg, 1, 2) lay.addWidget(self.lb_commi_mb_intvl, 2, 2) lay.addWidget(self.lb_commi_sb_avg, 3, 2) lay.addWidget(self.lb_commi_sb_intvl, 4, 2) lay.addWidget(self.lb_commi_tt_avg, 5, 2) lay.addWidget(self.lb_commi_tt_intvl, 6, 2) lay.addWidget(LbVHeader('Conditioning'), 0, 3) lay.addWidget(self.lb_condi_mb_avg, 1, 3) lay.addWidget(self.lb_condi_mb_intvl, 2, 3) lay.addWidget(self.lb_condi_sb_avg, 3, 3) lay.addWidget(self.lb_condi_sb_intvl, 4, 3) lay.addWidget(self.lb_condi_tt_avg, 5, 3) lay.addWidget(self.lb_condi_tt_intvl, 6, 3) lay.addWidget(LbVHeader('Machine Study'), 0, 4) lay.addWidget(self.lb_mstdy_mb_avg, 1, 4) lay.addWidget(self.lb_mstdy_mb_intvl, 2, 4) lay.addWidget(self.lb_mstdy_sb_avg, 3, 4) lay.addWidget(self.lb_mstdy_sb_intvl, 4, 4) lay.addWidget(self.lb_mstdy_tt_avg, 5, 4) lay.addWidget(self.lb_mstdy_tt_intvl, 6, 4) lay.addWidget(LbVHeader('All Stored Beam'), 0, 5) lay.addWidget(self.lb_stord_mb_avg, 1, 5) lay.addWidget(self.lb_stord_mb_intvl, 2, 5) lay.addWidget(self.lb_stord_sb_avg, 3, 5) lay.addWidget(self.lb_stord_sb_intvl, 4, 5) lay.addWidget(self.lb_stord_tt_avg, 5, 5) lay.addWidget(self.lb_stord_tt_intvl, 6, 5) return wid def _updateStoredCurrentStats(self, setup=False): shifttype = { 'mstdy': 'machinestudy', 'commi': 'commissioning', 'condi': 'conditioning', 'stord': 'ebeam', 'user': '******' } fillmode = {'mb': 'multibunch', 'sb': 'singlebunch', 'tt': 'total'} stats = { 'avg': ['average', 'stddev'], 'intvl': [ 'time', ] } for wsht, rsht in shifttype.items(): for wfm, rfm in fillmode.items(): for wstt, rstt in stats.items(): wid = getattr(self, 'lb_' + wsht + '_' + wfm + '_' + wstt) pname = 'current_' + rsht + '_' + rfm + '_' items = [getattr(self._macreport, pname + i) for i in rstt] if 'time' in rstt[0] and items[0] is not None: hour = int(items[0]) minu = int((items[0] - hour) * 60) items = [hour, minu] str2fmt = getattr( self, '_fst1' if ('time' in rstt[0]) else '_fs' + str(len(rstt))) text = '' if any([i is None for i in items]) \ else str2fmt.format(*items) wid.setText(text) if setup: wid.setToolTip( getattr(MacReport, pname + rstt[0]).__doc__) def _setupLightSourceUsageStats(self): self.lb_mstdy_fail_intvl = LbData('') self.lb_mstdy_fail_pcntl = LbData('') self.lb_mstdy_oper_intvl = LbData('') self.lb_mstdy_oper_pcntl = LbData('') self.lb_mstdy_total_intvl = LbData('') self.lb_mstdy_total_pcntl = LbData('') self.lb_commi_fail_intvl = LbData('') self.lb_commi_fail_pcntl = LbData('') self.lb_commi_oper_intvl = LbData('') self.lb_commi_oper_pcntl = LbData('') self.lb_commi_total_intvl = LbData('') self.lb_commi_total_pcntl = LbData('') self.lb_condi_fail_intvl = LbData('') self.lb_condi_fail_pcntl = LbData('') self.lb_condi_oper_intvl = LbData('') self.lb_condi_oper_pcntl = LbData('') self.lb_condi_total_intvl = LbData('') self.lb_condi_total_pcntl = LbData('') self.lb_maint_fail_intvl = LbData('') self.lb_maint_fail_pcntl = LbData('') self.lb_maint_oper_intvl = LbData('') self.lb_maint_oper_pcntl = LbData('') self.lb_maint_total_intvl = LbData('') self.lb_maint_total_pcntl = LbData('') self.lb_user_fail_intvl = LbData('') self.lb_user_fail_pcntl = LbData('') self.lb_user_oper_intvl = LbData('') self.lb_user_oper_pcntl = LbData('') self.lb_user_total_intvl = LbData('') self.lb_user_total_pcntl = LbData('') self.lb_total_intvl = LbHHeader('Total Usage Time (h): - ') wid = QWidget(self) lay = QGridLayout(wid) lay.setVerticalSpacing(0) lay.setHorizontalSpacing(0) lay.setAlignment(Qt.AlignTop) lay.addWidget(LbHHeader('Operational Time (h)'), 1, 0) lay.addWidget(LbHHeader('Operational Percentage (%)'), 2, 0) lay.addWidget(LbHHeader('Failures Time (h)'), 3, 0) lay.addWidget(LbHHeader('Failures Percentage (%)'), 4, 0) lay.addWidget(LbHHeader('Shift Time (h)'), 5, 0) lay.addWidget(LbHHeader('Shift Percentage (%)'), 6, 0) lay.addWidget(self.lb_total_intvl, 7, 0, 1, 6) lay.addWidget(LbVHeader('Users'), 0, 1) lay.addWidget(self.lb_user_oper_intvl, 1, 1) lay.addWidget(self.lb_user_oper_pcntl, 2, 1) lay.addWidget(self.lb_user_fail_intvl, 3, 1) lay.addWidget(self.lb_user_fail_pcntl, 4, 1) lay.addWidget(self.lb_user_total_intvl, 5, 1) lay.addWidget(self.lb_user_total_pcntl, 6, 1) lay.addWidget(LbVHeader('Commissioning'), 0, 2) lay.addWidget(self.lb_commi_oper_intvl, 1, 2) lay.addWidget(self.lb_commi_oper_pcntl, 2, 2) lay.addWidget(self.lb_commi_fail_intvl, 3, 2) lay.addWidget(self.lb_commi_fail_pcntl, 4, 2) lay.addWidget(self.lb_commi_total_intvl, 5, 2) lay.addWidget(self.lb_commi_total_pcntl, 6, 2) lay.addWidget(LbVHeader('Conditioning'), 0, 3) lay.addWidget(self.lb_condi_oper_intvl, 1, 3) lay.addWidget(self.lb_condi_oper_pcntl, 2, 3) lay.addWidget(self.lb_condi_fail_intvl, 3, 3) lay.addWidget(self.lb_condi_fail_pcntl, 4, 3) lay.addWidget(self.lb_condi_total_intvl, 5, 3) lay.addWidget(self.lb_condi_total_pcntl, 6, 3) lay.addWidget(LbVHeader('Machine Study'), 0, 4) lay.addWidget(self.lb_mstdy_oper_intvl, 1, 4) lay.addWidget(self.lb_mstdy_oper_pcntl, 2, 4) lay.addWidget(self.lb_mstdy_fail_intvl, 3, 4) lay.addWidget(self.lb_mstdy_fail_pcntl, 4, 4) lay.addWidget(self.lb_mstdy_total_intvl, 5, 4) lay.addWidget(self.lb_mstdy_total_pcntl, 6, 4) lay.addWidget(LbVHeader('Maintenance'), 0, 5) lay.addWidget(self.lb_maint_oper_intvl, 1, 5) lay.addWidget(self.lb_maint_oper_pcntl, 2, 5) lay.addWidget(self.lb_maint_fail_intvl, 3, 5) lay.addWidget(self.lb_maint_fail_pcntl, 4, 5) lay.addWidget(self.lb_maint_total_intvl, 5, 5) lay.addWidget(self.lb_maint_total_pcntl, 6, 5) return wid def _updateLightSourceUsageStats(self, setup=False): shifttype = { 'mstdy': 'machinestudy', 'commi': 'commissioning', 'condi': 'conditioning', 'maint': 'maintenance', 'user': '******' } intervaltype = { 'fail': '_failures', 'oper': '_operational', 'total': '' } for wst, rst in shifttype.items(): for wit, rit in intervaltype.items(): widt = getattr(self, 'lb_' + wst + '_' + wit + '_intvl') tname = 'lsusage_' + rst + rit + '_time' tval = getattr(self._macreport, tname) if tval is None: text = '' else: hour = int(tval) minu = int((tval - hour) * 60) text = self._fst1.format(hour, minu) widt.setText(text) if setup: widt.setToolTip(getattr(MacReport, tname).__doc__) widp = getattr(self, 'lb_' + wst + '_' + wit + '_pcntl') pname = 'lsusage_' + rst + rit pval = getattr(self._macreport, pname) text = '' if pval is None else self._fs1.format(pval) widp.setText(text) if setup: widp.setToolTip(getattr(MacReport, pname).__doc__) text = 'Total Usage Time (h): ' if self._macreport.lsusage_total_time is not None: val = self._macreport.lsusage_total_time hour = int(val) minu = int((val - hour) * 60) text += self._fst1.format(hour, minu) self.lb_total_intvl.setText(text) def _do_update(self): if self.sender().text() == 'Abort': self._update_task.terminate() now = Time.now().strftime('%Y/%m/%d-%H:%M:%S') item = QListWidgetItem(now + ' Aborted.') self._progress_list.addItem(item) self._progress_list.scrollToBottom() self._setup_search_button() else: if self.dt_start.dateTime() >= self.dt_stop.dateTime() or \ self.dt_start.dateTime() > Time.now() or \ self.dt_stop.dateTime() > Time.now(): QMessageBox.warning(self, 'Ops...', 'Insert a valid time interval.') return self._macreport.timestamp_start = \ self.dt_start.dateTime().toSecsSinceEpoch() self._macreport.timestamp_stop = \ self.dt_stop.dateTime().toSecsSinceEpoch() self._progress_list.clear() self._pb_showraw.setEnabled(False) self._pb_showpvsd.setEnabled(False) self._setup_search_button() self._update_task = UpdateTask(self._macreport) self._update_task.updated.connect(self._update_progress) self._update_task.start() def _update_progress(self, message): item = QListWidgetItem(message) self._progress_list.addItem(item) self._progress_list.scrollToBottom() if 'Collected' in message: self._setup_search_button() self._updateUserShiftStats() self._updateStoredCurrentStats() self._updateLightSourceUsageStats() self._pb_showraw.setEnabled(True) self._pb_showpvsd.setEnabled(True) def _setup_search_button(self): if self.pb_search.text() == 'Abort': self.pb_search.setIcon(qta.icon('fa5s.search')) self.pb_search.setText('Search') else: self.pb_search.setIcon( qta.icon('fa5s.spinner', animation=qta.Spin(self.pb_search))) self.pb_search.setText('Abort') def _show_raw_data(self): fig = self._macreport.plot_raw_data() wid = MatplotlibWidget(fig) wid.setWindowTitle('Machine Reports - Raw Data (' + str(self._macreport.time_start) + ' -> ' + str(self._macreport.time_stop) + ')') wid.show() def _show_progmd_vs_delivd(self): fig = self._macreport.plot_progmd_vs_delivd_hours() wid = MatplotlibWidget(fig) wid.setWindowTitle( 'Machine Reports - Programmed vs. Delivered Hours (' + str(self._macreport.time_start) + ' -> ' + str(self._macreport.time_stop) + ')') wid.show()