class AbsoluteRelativeSpinBox(QWidget): editingFinished = pyqtSignal() valueChanged = pyqtSignal() def __init__(self, *args, **kwargs): super().__init__(*args) layout = QStackedLayout(self) self.double_spin = QDoubleSpinBox() self.double_spin.valueChanged.connect(self.double_value_changed) self.double_spin.editingFinished.connect(self.double_editing_finished) layout.addWidget(self.double_spin) self.int_spin = QSpinBox() self.int_spin.setMaximum(10**4) self.int_spin.valueChanged.connect(self.int_value_changed) self.int_spin.editingFinished.connect(self.int_editing_finished) layout.addWidget(self.int_spin) self.setValue(kwargs.get('value', 0.)) def double_value_changed(self): if self.double_spin.value() > 1: self.layout().setCurrentIndex(1) self.int_spin.setValue(self.double_spin.value()) self.valueChanged.emit() def double_editing_finished(self): if self.double_spin.value() <= 1.: self.editingFinished.emit() def int_value_changed(self): if self.int_spin.value() == 0: self.layout().setCurrentIndex(0) self.double_spin.setValue(1. - self.double_spin.singleStep()) # There is no need to emit valueChanged signal. def int_editing_finished(self): if self.int_spin.value() > 0: self.editingFinished.emit() def value(self): return self.int_spin.value() or self.double_spin.value() def setValue(self, value): if isinstance(value, int): self.layout().setCurrentIndex(1) self.int_spin.setValue(value) else: self.layout().setCurrentIndex(0) self.double_spin.setValue(value) def setSingleStep(self, step): if isinstance(step, float): self.double_spin.setSingleStep(step) else: self.int_spin.setSingleStep(step)
class ObjectFiller(QDialog): msg_sig = pyqtSignal(str) # Display this message to the operator oyn_sig = pyqtSignal(str) # Request for operator yes/no def __init__(self, form=None, parent=None): "Create and display the GUI, but do not start it." self.result = None self.form = form log.info("Creating GUI object") super().__init__(parent=parent) self.ui_font = QFont("Microsoft Sans Serif", 12, QFont.Bold) self.body_font = QFont("Cooper", 48, QFont.Bold) self.setFont(self.ui_font) self.app_title = "JSON Forms" self.initUI() self.tr_thread = TimerThread(self) self.tr_thread.start() self.show() def initUI(self): "Create the GUI layout to be used in the tests." log.info("Initialising the UI") self.setWindowTitle(self.app_title) ## Create all necessary widgets ## Short alternate names make configuration simpler. ## Buttons self.button_bar = QDialogButtonBox.Ok | QDialogButtonBox.Cancel self.button_box = QDialogButtonBox(self.button_bar) ## Bring all the HBoxes together in a VBox vbox = QVBoxLayout() self.grid = self.form.render() vbox.addLayout(self.grid) vbox.addWidget(self.button_box) ## Connect UI signals to slots self.button_box.accepted.connect(self.accept) self.button_box.rejected.connect(self.reject) ## Establish the window layout self.setLayout(vbox) ## Set pints.components to desired initial state ## tb.setEnabled(False) ## sn.setEnabled(False) self.setGeometry(300, 300, 300, 250) def get_value(self): msgs = self.form.validate() return {f.name: f.get_value() for f in self.form.fields} def show_message(self, msg): self.messageArea.setText(msg) def add_message(self, msg): ma = self.messageArea ma.setText(f"{ma.text()}\n\n{msg}")
class Emitter(QObject, PyOwned): signal = pyqtSignal() _p_signal = pyqtSignal() def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # queued signal -> signal connection self._p_signal.connect(self.signal, Qt.QueuedConnection) def schedule_emit(self): """Schedule `signal` emit""" self._p_signal.emit()
class RunAlignmentWorker(QObject): progress = pyqtSignal(int, name="runContainerProgress") finished = pyqtSignal(name="runContainerFinished") container_ref_dir = "/root/LINCS/References" container_seq_dir = "/root/LINCS/Seqs" container_counts_dir = "/root/LINCS/Counts" commands = [ "cd /root/LINCS/; " "Programs/Broad-DGE/run-alignment-analysis.sh >& run-alignment-analysis.log; " "exit" ] def __init__(self, cli, image_name, host_ref_dir, host_seq_dir, host_counts_dir): super().__init__() self.docker = cli self.image_name = image_name self.host_ref_dir = host_ref_dir self.host_seq_dir = host_seq_dir self.host_counts_dir = host_counts_dir self.containerId = "" def work(self): volumes = { self.host_ref_dir: self.container_ref_dir, self.host_seq_dir: self.container_seq_dir, self.host_counts_dir: self.container_counts_dir } response = self.docker.create_container(self.image_name, volumes=volumes, commands=self.commands) if response['Warnings'] is None: self.containerId = response['Id'] self.docker.start_container(self.containerId) else: # TODO emit warning to Widget print(response['Warnings']) i = 1 # Keep running until container is exited while self.docker.isRunning(self.containerId): # self.docker.printStats(self.containerId) self.progress.emit(i) time.sleep(2) i += 2 # Remove the container now that it is finished self.docker.remove_container(self.containerId) self.finished.emit()
class PredictionsModel(AbstractSortTableModel): list_sorted = pyqtSignal() def __init__(self, values=None, probs=None, headers=None, parent=None): super().__init__(parent) self._values = values self._probs = probs self.__probInd = None if values is not None: assert len(self._values) == len(self._probs) != 0 sizes = {len(x) for c in (values, probs) for x in c} assert len(sizes) == 1 self.__columnCount = len(values) self.__rowCount = sizes.pop() if headers is None: headers = [None] * self.__columnCount else: assert probs is None assert headers is None self.__columnCount = self.__rowCount = 0 self._header = headers def rowCount(self, parent=QModelIndex()): return 0 if parent.isValid() else self.__rowCount def columnCount(self, parent=QModelIndex()): return 0 if parent.isValid() else self.__columnCount def data(self, index, role=Qt.DisplayRole): if role in (Qt.DisplayRole, Qt.EditRole): column = index.column() row = self.mapToSourceRows(index.row()) return self._values[column][row], self._probs[column][row] return None def headerData(self, section, orientation, role=Qt.DisplayRole): if role == Qt.DisplayRole: if orientation == Qt.Vertical: return str(section + 1) elif self._header is not None and section < len(self._header): return self._header[section] return None def setProbInd(self, indices): self.__probInd = indices self.sort(self.sortColumn()) def sortColumnData(self, column): values = self._values[column] probs = self._probs[column] # Let us assume that probs can be None, numpy array or list of arrays if probs is not None and len(probs) and len(probs[0]) \ and self.__probInd is not None and len(self.__probInd): return probs[:, self.__probInd] else: return values def sort(self, column, order=Qt.AscendingOrder): super().sort(column, order) self.list_sorted.emit()
class _JSObjectChannel(QObject): """ This class hopefully prevent options data from being marshalled into a string-like dumb (JSON) object when passed into JavaScript. Or at least relies on Qt to do it as optimally as it knows to.""" # JS webchannel listens to this signal objectChanged = pyqtSignal('QVariantMap') def __init__(self, parent): super().__init__(parent) self._obj = None self._id_gen = count() self._objects = {} def send_object(self, name, obj): if isinstance(obj, QObject): raise ValueError( "QWebChannel doesn't transmit QObject instances. If you " "need a QObject available in JavaScript, pass it as a " "bridge in WebviewWidget constructor.") id = next(self._id_gen) value = self._objects[id] = dict(id=id, name=name, obj=obj) # Wait till JS is connected to receive objects wait(until=lambda: self.receivers(self.objectChanged)) self.objectChanged.emit(value) @pyqtSlot(int) def mark_exposed(self, id): del self._objects[id] def is_all_exposed(self): return len(self._objects) == 0
class LocalContainerRunner(QThread): progress = pyqtSignal(int) def __init__(self, cli, image_name, volumes, commands, environments=None): QThread.__init__(self) self.docker = cli self.image_name = image_name self.volumes = volumes self.commands = commands self.environments = environments self.containerId = "" self.Flag_isRunning = False def __del__(self): self.wait() def run(self): response = self.docker.create_container(self.image_name, volumes=self.volumes, commands=self.commands, environment=self.environments) if response['Warnings'] == None: self.containerId = response['Id'] self.docker.start_container(self.containerId) else: print(response['Warnings']) # Keep running until container is exited while self.docker.container_running(self.containerId): self.sleep(1) # Remove the container when it is finished self.docker.remove_container(self.containerId)
class SortProxyModel(QSortFilterProxyModel): """ QSortFilter model used in both TableView and PredictionsView """ list_sorted = pyqtSignal() def __init__(self, parent=None): super().__init__(parent) self.__sortInd = None def setSortIndices(self, indices): if indices is not None: indices = numpy.array(indices, dtype=numpy.int) if indices.shape != (self.rowCount(), ): raise ValueError("indices.shape != (self.rowCount(),)") indices.flags.writeable = False self.__sortInd = indices if self.__sortInd is not None: self.custom_sort(0) # need valid order to call lessThan def lessThan(self, left, right): if self.__sortInd is None: return super().lessThan(left, right) assert not (left.parent().isValid() or right.parent().isValid()), \ "Not a table model" rleft, rright = left.row(), right.row() try: ileft, iright = self.__sortInd[rleft], self.__sortInd[rright] except IndexError: return False else: return ileft < iright def isSorted(self): return self.__sortInd is not None def sort(self, n, order=Qt.AscendingOrder): """ This sort is called only on click, in other cases we manually call custom_sort """ # reset sort - otherwise when same parameters set by lessThan function # clicking on header would not trigger resort self.__sortInd = None self.custom_sort(n, order=order) self.list_sorted.emit() def custom_sort(self, n, order=Qt.AscendingOrder): """ When sorting is dmanded because of sort change in the other view this sorting is called. It will not reset __sortInd to None. """ if self.sortColumn() == n and self.sortOrder() == order: self.invalidate() else: super().sort(n, order) # need some valid sort column
class TopicWidget(gui.OWComponent, QGroupBox): Model = NotImplemented valueChanged = pyqtSignal(object) parameters = () spin_format = '{description}:' def __init__(self, master, **kwargs): QGroupBox.__init__(self, **kwargs) gui.OWComponent.__init__(self, master) self.model = self.create_model() QVBoxLayout(self) for parameter, description, minv, maxv, step, _type in self.parameters: spin = gui.spin(self, self, parameter, minv=minv, maxv=maxv, step=step, label=self.spin_format.format(description=description, parameter=parameter), labelWidth=220, spinType=_type) spin.clearFocus() spin.editingFinished.connect(self.on_change) def on_change(self): self.model = self.create_model() self.valueChanged.emit(self) def create_model(self): return self.Model(**{par[0]: getattr(self, par[0]) for par in self.parameters}) def report_model(self): return self.model.name, ((par[1], getattr(self, par[0])) for par in self.parameters)
class GetLatestVersion(QThread): resultReady = pyqtSignal(str) def run(self): try: request = Request( "https://orange.biolab.si/version/", headers={ "Accept": "text/plain", "Accept-Encoding": "gzip, deflate", "Connection": "close", "User-Agent": self.ua_string(), }, ) contents = urlopen(request, timeout=10).read().decode() # Nothing that this fails with should make Orange crash except Exception: # pylint: disable=broad-except log.exception("Failed to check for updates") else: self.resultReady.emit(contents) @staticmethod def ua_string(): is_anaconda = "Continuum" in sys.version or "conda" in sys.version return "Orange{orange_version}:Python{py_version}:{platform}:{conda}".format( orange_version=current, py_version=".".join(sys.version[:3]), platform=sys.platform, conda="Anaconda" if is_anaconda else "", )
class GetLatestVersion(QThread): resultReady = pyqtSignal(str) def run(self): try: request = Request('https://orange.biolab.si/version/', headers={ 'Accept': 'text/plain', 'Accept-Encoding': 'gzip, deflate', 'Connection': 'close', 'User-Agent': self.ua_string() }) contents = urlopen(request, timeout=10).read().decode() # Nothing that this fails with should make Orange crash except Exception: # pylint: disable=broad-except log.exception('Failed to check for updates') else: self.resultReady.emit(contents) @staticmethod def ua_string(): is_anaconda = 'Continuum' in sys.version or 'conda' in sys.version return 'Orange{orange_version}:Python{py_version}:{platform}:{conda}'.format( orange_version=current, py_version='.'.join(sys.version[:3]), platform=sys.platform, conda='Anaconda' if is_anaconda else '', )
class _FinishedMonitor(QObject): finished = pyqtSignal() def __init__(self, widget: 'OWBaseWidget') -> None: super().__init__(None) self.widget = widget self.sm = widget.signalManager # type: DummySignalManager widget.widgetStateChanged.connect(self._changed) self._finished = self.is_finished() self.invalidated_outputs = self.sm.invalidated_outputs(widget) for output in self.invalidated_outputs: output.completed.connect(self._completed, Qt.UniqueConnection) def is_finished(self) -> bool: finished = not (self.widget.isInvalidated() or self.sm.has_invalidated_outputs(self.widget)) return finished @pyqtSlot() def _changed(self): fin = self.is_finished() self.invalidated_outputs = self.sm.invalidated_outputs(self.widget) for output in self.invalidated_outputs: try: output.completed.connect(self._completed, Qt.UniqueConnection) except TypeError: # connection already exists pass if fin and fin != self._finished: self.finished.emit() @pyqtSlot() def _completed(self): self._changed()
class OnOffButton(QPushButton): stateChanged = pyqtSignal() def __init__(self, enabled=True, on_button='on_button.png', off_button='off_button.png', size=(26, 26), *__args): super().__init__(*__args) self.on_icon = QIcon(_i(on_button)) self.off_icon = QIcon(_i(off_button)) self.setAutoDefault(False) # do not toggle on Enter self.setFlat(True) self.setIconSize(QSize(*size)) self.setStyleSheet('border:none') self.state = enabled self.clicked.connect(self.change_state) self.update_icon() def change_state(self): self.state = not self.state self.update_icon() self.stateChanged.emit() def update_icon(self): self.setIcon(self.on_icon if self.state else self.off_icon) def sizeHint(self): return QSize(26, 26)
class _JSObjectChannel(QObject): """ This class hopefully prevent options data from being marshalled into a string-like dumb (JSON) object when passed into JavaScript. Or at least relies on Qt to do it as optimally as it knows to.""" # JS webchannel listens to this signal objectChanged = pyqtSignal('QVariantMap') def __init__(self, parent): super().__init__(parent) self._obj = None self._id_gen = count() self._objects = {} def send_object(self, name, obj): id = next(self._id_gen) value = self._objects[id] = dict(id=id, name=name, obj=obj) # Wait till JS is connected to receive objects while not self.receivers(self.objectChanged): qApp.processEvents(QEventLoop.ExcludeUserInputEvents) self.objectChanged.emit(value) @pyqtSlot(int) def mark_exposed(self, id): del self._objects[id] def is_all_exposed(self): return len(self._objects) == 0
class TopicViewer(QTreeWidget): """ Just keeps stuff organized. Holds topic visualization widget and related functions. """ columns = ['Topic', 'Topic keywords'] topicSelected = pyqtSignal(object) def __init__(self): super().__init__() self.setColumnCount(len(self.columns)) self.setHeaderLabels(self.columns) self.resize_columns() self.itemSelectionChanged.connect(self.selected_topic_changed) self.setItemDelegate(HTMLDelegate()) # enable colors self.selected_id = None def resize_columns(self): for i in range(self.columnCount()): self.resizeColumnToContents(i) def show_model(self, topic_model, pos_tags=False): self.clear() if topic_model.model: for i in range(topic_model.num_topics): words, weights = topic_model.get_top_words_by_id(i) if words: it = TopicViewerTreeWidgetItem( i, words, weights, self, color_by_weights=topic_model.has_negative_weights, pos_tags=pos_tags) self.addTopLevelItem(it) self.resize_columns() self.setCurrentItem(self.topLevelItem(0)) def selected_topic_changed(self): selected = self.selectedItems() if selected: self.select(selected[0].topic_id) self.topicSelected.emit(self.selected_id) else: self.topicSelected.emit(None) def report(self): root = self.invisibleRootItem() child_count = root.childCount() return [root.child(i).report() for i in range(child_count)] def sizeHint(self): return QSize(700, 300) def select(self, index): self.selected_id = index self.setCurrentItem(self.topLevelItem(index))
class ProjectsWindow(object): """ See: - pyforms_generic_editor.models.projects.__init__.py - pyforms_generic_editor.models.projects.projects_window.py """ signal_session_create_treenode = pyqtSignal(Session) def __init__(self, mainwindow=None): super(ProjectsWindow, self).__init__(mainwindow) def register_on_toolbar(self, toolbar): toolbar += [ ControlToolButton('New', icon=conf.NEW_SMALL_ICON, default=self.create_project, maxheight=30), ControlToolButton('Open', icon=conf.OPEN_SMALL_ICON, default=self._option_open_project, maxheight=30), ControlToolButton('Save', icon=conf.SAVE_SMALL_ICON, default=self.save_current_project, maxheight=30), '|' ] def create_project(self): """ Invoke project creation .. seealso:: * Create project treenode: :class:`pybpodgui_plugin.models.projects.projects_treenode.ProjectsTreeNode.create_project`. :rtype: Project """ return Project(self) def open_project(self, project_path=None): """ Open project .. seealso:: * Open project treenode: :class:`pybpodgui_plugin.models.projects.projects_treenode.ProjectsTreeNode.open_project`. :param str project_path: """ project = None if not project_path: project_path = QFileDialog.getExistingDirectory( self, "Select the project directory") if project_path: project = self.create_project() project.load(str(project_path)) return project
class ImageLabel(QLabel): mReleased = pyqtSignal() def __init__(self, *args): super(ImageLabel, self).__init__(*args) def mouseReleaseEvent(self, QMouseEvent): super(QLabel, self).mouseReleaseEvent(QMouseEvent) self.mReleased.emit()
class GyroImage(QLabel): mReleased = pyqtSignal() def __init__(self, path, parent, direction, fixedSize=250, scaleHeight=None, scaleWidth=None, compassRotation=0): super(GyroImage, self).__init__() self.setAlignment(Qt.AlignCenter) self.setFixedWidth(fixedSize) self.setFixedHeight(fixedSize) self.parent = parent self.compassImage = QImage(Config.icons['gyro']['compass']['path']).scaledToWidth(self.width()) if scaleWidth is not None: self.image = QImage(path).scaledToWidth(scaleWidth) elif scaleHeight is not None: self.image = QImage(path).scaledToHeight(scaleHeight) else: self.image = QImage(path) self.direction = direction self.compassRotation = compassRotation def paintEvent(self, QPaintEvent): import math if self.direction == 'x': _angle = self.parent.rotationX _x1 = self.width() / 2 _y1 = self.height() / 2 _x2 = math.cos(math.radians(_angle)) * (self.width() / 2) _y2 = math.sin(math.radians(_angle)) * (self.width() / 2) elif self.direction == 'y': _angle = self.parent.rotationY _x1 = self.width() / 2 _y1 = self.height() / 2 _x2 = math.cos(math.radians(_angle + 90)) * (self.height() / 2) _y2 = math.sin(math.radians(_angle + 90)) * (self.height() / 2) else: _angle = 0 _x1 = 0 _y1 = 0 _x2 = 0 _y2 = 0 _painter = QPainter(self) _pm = QPixmap(self.width(), self.height()) _pm_compass = QPixmap(self.compassImage).transformed(QTransform().rotate(self.compassRotation)) _pm_image = QPixmap(self.image).transformed(QTransform().rotate(_angle)) _painter.drawPixmap(0, 0, _pm_compass) _painter.setPen(QColor(255, 160, 47)) _painter.drawLine(_x1, _y1, _x2, _y2) _x = (self.width() - _pm_image.width()) / 2 _y = (self.height() - _pm_image.height()) / 2 _painter.drawPixmap(_x, _y, _pm_image) _painter.end() def mouseReleaseEvent(self, QMouseEvent): super(QLabel, self).mouseReleaseEvent(QMouseEvent) self.mReleased.emit()
class GetLatestVersion(QThread): resultReady = pyqtSignal(str) def run(self): try: self.resultReady.emit( urlopen('https://orange.biolab.si/version/', timeout=10).read().decode()) except OSError: log.exception('Failed to check for updates')
class RunAlignmentThread(QThread): progress = pyqtSignal(int) container_ref_dir = "/root/LINCS/References" container_seq_dir = "/root/LINCS/Seqs" container_counts_dir = "/root/LINCS/Counts" container_aligns_dir = "/root/LINCS/Aligns" commands = [ "/root/LINCS/Programs/Broad-DGE/run-alignment-analysis.sh >& /root/LINCS/Counts/run-alignment-analysis.log; " "exit" ] def __init__(self, cli, image_name, host_ref_dir, host_seq_dir, host_counts_dir, host_aligns_dir): QThread.__init__(self) self.docker = cli self.image_name = image_name self.host_ref_dir = host_ref_dir self.host_seq_dir = host_seq_dir self.host_counts_dir = host_counts_dir self.host_aligns_dir = host_aligns_dir self.containerId = "" def __del__(self): self.wait() def run(self): volumes = { self.host_ref_dir: self.container_ref_dir, self.host_seq_dir: self.container_seq_dir, self.host_counts_dir: self.container_counts_dir, self.host_aligns_dir: self.container_aligns_dir } response = self.docker.create_container(self.image_name, volumes=volumes, commands=self.commands) if response['Warnings'] == None: self.containerId = response['Id'] self.docker.start_container(self.containerId) else: print(response['Warnings']) #i = 1 # Keep running until container is exited while self.docker.container_running(self.containerId): time.sleep(2) pass # self.docker.printStats(self.containerId) #self.progress.emit(i) #time.sleep(2) #i += 2 # Remove the container now that it is finished self.docker.remove_container(self.containerId)
class LeafletChoropleth(WebviewWidget): selectionChanged = pyqtSignal(list) def __init__(self, parent=None): class Bridge(QObject): @pyqtSlot() def fit_to_bounds(_): return self.fit_to_bounds() @pyqtSlot('QVariantList') def selection(_, selected): self.selectionChanged.emit(selected) super().__init__(parent, bridge=Bridge(), url=QUrl( self.toFileURL( os.path.join(os.path.dirname(__file__), '_leaflet', 'owchoropleth.html')))) self._owwidget = parent self.bounds = None def fit_to_bounds(self): if self.bounds is None: return east, south, west, north = self.bounds maxzoom = 5 if self._owwidget.admin == 0 else 7 self.evalJS(''' map.flyToBounds([[%f, %f], [%f, %f]], { padding: [0,0], minZoom: 2, maxZoom: %d, duration: .6, easeLinearity: .4 });''' % (north, west, south, east, maxzoom)) def set_opacity(self, opacity): self.evalJS('''set_opacity(%f);''' % (opacity / 100)) def set_quantization(self, quantization): self.evalJS('''set_quantization("%s");''' % (quantization[0].lower())) def set_color_steps(self, steps): self.evalJS('''set_color_steps(%d);''' % steps) def toggle_legend(self, visible): self.evalJS('''toggle_legend(%d);''' % (int(bool(visible)))) def toggle_map_labels(self, visible): self.evalJS('''toggle_map_labels(%d);''' % (int(bool(visible)))) def toggle_tooltip_details(self, visible): self.evalJS('''toggle_tooltip_details(%d);''' % (int(bool(visible)))) def preset_region_selection(self, selection): self.evalJS('''set_region_selection(%s);''' % selection)
class GetLatestVersion(QThread): resultReady = pyqtSignal(str) def run(self): try: self.resultReady.emit( urlopen('https://orange.biolab.si/version/', timeout=10).read().decode()) # Nothing that this fails with should make Orange crash except Exception: # pylint: disable=broad-except log.exception('Failed to check for updates')
class DownloadTask(Task): exception = pyqtSignal(Exception) def __init__(self, res): super().__init__() self.res = res def run(self): try: return list(self.res.get_samples()) except requests.exceptions.ConnectionError as e: self.exception.emit(e)
class TreeGraphicsView(QGraphicsView): resized = pyqtSignal(QSize, name="resized") def __init__(self, scene, *args): super().__init__(scene, *args) self.viewport().setMouseTracking(True) self.setFocusPolicy(Qt.WheelFocus) self.setRenderHint(QPainter.Antialiasing) self.setRenderHint(QPainter.TextAntialiasing) def resizeEvent(self, event): super().resizeEvent(event) self.resized.emit(self.size())
class ResourceLoader(QWidget, OWComponent): valueChanged = pyqtSignal(str, str) recent_files = settings.Setting([]) recent_provider = settings.Setting([]) resource_path = settings.Setting('') def __init__(self, widget, model_format, provider_format, model_button_label='Model', provider_button_label='Provider'): QWidget.__init__(self) OWComponent.__init__(self, widget) self.model_path = None layout = QHBoxLayout(self) layout.setContentsMargins(0, 0, 0, 0) self.model_widget = FileWidget(recent_files=self.recent_files, dialog_title='Load model', dialog_format=model_format, start_dir=None, on_open=self.load_model, allow_empty=False, reload_button=False, browse_label=model_button_label) self.model_path = self.recent_files[0] if self.recent_files else None layout.addWidget(self.model_widget) self.provider_widget = FileWidget(recent_files=self.recent_provider, dialog_title='Load provider', dialog_format=provider_format, start_dir=None, on_open=self.load_provider, allow_empty=False, reload_button=False, browse_label=provider_button_label) layout.addWidget(self.provider_widget) def load_model(self, path_to_file): self.model_path = path_to_file self.valueChanged.emit(self.model_path, self.resource_path) def load_provider(self, path_to_file): self.resource_path = path_to_file self.valueChanged.emit(self.model_path, self.resource_path)
class MockWidget(OWWidget): name = 'MockWidget' want_main_area = False filter_component = SettingProvider(CollapsibleFilterComponent) pagination_component = SettingProvider(PaginationComponent) pagination_availability = pyqtSignal(bool, bool) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.filter_component = CollapsibleFilterComponent( self, self.controlArea) self.pagination_component = PaginationComponent(self, self.controlArea) self.sign_in_dialog = SignInForm(self)
class LineEdit(QLineEdit): kb = pyqtSignal() def __init__(self, *args): super(LineEdit, self).__init__(*args) def mousePressEvent(self, QMouseEvent): super(LineEdit, self).mousePressEvent(QMouseEvent) self.kb.emit() def focusOutEvent(self, event): super(LineEdit, self).focusOutEvent(event) if self.parent().focusWidget() != self: self.window().dock.hide() self.window().osk.rWidget = None
class TableView(gui.TableView): selected_row = pyqtSignal(int) def __init__(self, parent): super().__init__(parent, selectionMode=self.SingleSelection) self._parent = parent self.bold_font = self.BoldFontDelegate( self) # member because PyQt sometimes unrefs too early for column in range(2, 100, 2): self.setItemDelegateForColumn(column, self.bold_font) self.horizontalHeader().setVisible(False) def selectionChanged(self, selected, deselected): super().selectionChanged(selected, deselected) self.selected_row.emit( selected.indexes()[0].row() if len(selected) else -1)
class OWButton(QToolButton): ''' A custom tool button which signal when its down state changes ''' downChanged = pyqtSignal(bool) def __init__(self, action=None, parent=None): QToolButton.__init__(self, parent) self.setMinimumSize(30, 30) if action: self.setDefaultAction(action) def setDown(self, down): if self.isDown() != down: self.downChanged[bool].emit(down) QToolButton.setDown(self, down)
class GetLatestVersion(QThread): resultReady = pyqtSignal(str) def run(self): try: request = Request('https://orange.biolab.si/version/', headers={ 'Accept': 'text/plain', 'Accept-Encoding': 'gzip, deflate', 'Connection': 'close', 'User-Agent': ua_string()}) contents = urlopen(request, timeout=10).read().decode() # Nothing that this fails with should make Orange crash except Exception: # pylint: disable=broad-except log.exception('Failed to check for updates') else: self.resultReady.emit(contents)