def __init__(self, parent, **kwargs): # Qt initialization super(DicomWidget, self).__init__(parent, **kwargs) self.setCursor(QtCore.Qt.CrossCursor) self.setMouseTracking(True) # Inner data self._zoom_level = kwargs.get("zoom_level", 0) self._data = kwargs.get("data", None) self._scaled_image = None self._low_hu = kwargs.get("low_hu", -1000) self._high_hu = kwargs.get("high_hu", 3000) self._plane = kwargs.get("plane", dicom_data.AXIAL) self._slice = kwargs.get("slice", 0) self._color_table = kwargs.get("color_table", [QtGui.qRgb(i, i, i) for i in range(256)]) self._image = None self._pixmap = None # Signals & slots self._auto_wire() self.update_image()
def CreateTopImage(width, title, payload_description, text): text_extent_qt_image = HG.client_controller.bitmap_manager.GetQtImage( 20, 20, 24) painter = QG.QPainter(text_extent_qt_image) text_font = QW.QApplication.font() basic_font_size = text_font.pointSize() payload_description_font = QW.QApplication.font() payload_description_font.setPointSize(int(basic_font_size * 1.4)) title_font = QW.QApplication.font() title_font.setPointSize(int(basic_font_size * 2.0)) texts_to_draw = [] current_y = 6 for (t, f) in ((title, title_font), (payload_description, payload_description_font), (text, text_font)): painter.setFont(f) wrapped_texts = WrapText(painter, t, width - 20) line_height = painter.fontMetrics().height() wrapped_texts_with_ys = [] if len(wrapped_texts) > 0: current_y += 10 for wrapped_text in wrapped_texts: wrapped_texts_with_ys.append((wrapped_text, current_y)) current_y += line_height + 4 texts_to_draw.append((wrapped_texts_with_ys, f)) current_y += 6 top_height = current_y del painter del text_extent_qt_image # top_qt_image = HG.client_controller.bitmap_manager.GetQtImage( width, top_height, 24) painter = QG.QPainter(top_qt_image) painter.setBackground(QG.QBrush(QC.Qt.white)) painter.eraseRect(painter.viewport()) # painter.drawPixmap(width - 16 - 5, 5, CC.global_pixmaps().file_repository) # for (wrapped_texts_with_ys, f) in texts_to_draw: painter.setFont(f) for (wrapped_text, y) in wrapped_texts_with_ys: text_size = painter.fontMetrics().size(QC.Qt.TextSingleLine, wrapped_text) QP.DrawText(painter, (width - text_size.width()) // 2, y, wrapped_text) del painter data_bytearray = top_qt_image.bits() if QP.qtpy.PYSIDE2: data_bytes = bytes(data_bytearray) elif QP.qtpy.PYQT5: data_bytes = data_bytearray.asstring(top_height * width * 3) top_image_rgb = numpy.fromstring(data_bytes, dtype='uint8').reshape( (top_height, width, 3)) top_image = cv2.cvtColor(top_image_rgb, cv2.COLOR_RGB2GRAY) top_height_header = struct.pack('!H', top_height) byte0 = top_height_header[0:1] byte1 = top_height_header[1:2] top_image[0][0] = ord(byte0) top_image[0][1] = ord(byte1) return top_image
def keyPressEvent(self, event): """ Make LeftArrow to work on non-directories. When LeftArrow is pressed on a file entry or an unexpanded directory, then move the current index to the parent directory. This simplifies navigation using the keyboard. For power-users, we support Vim keybindings ;-P """ # Check whether the item is expanded before calling the base class # keyPressEvent otherwise we end up collapsing and changing the # current index in one shot, which we don't want to do. widget = self.widget index = widget.currentIndex() was_expanded = widget.isExpanded(index) was_collapsed = not was_expanded # Vim keybindings... # Rewrite the event before marshalling to QTreeView.event() key = event.key() # Remap 'H' to 'Left' if key == Qt.Key_H: event = QtGui.QKeyEvent(event.type(), Qt.Key_Left, event.modifiers()) # Remap 'J' to 'Down' elif key == Qt.Key_J: event = QtGui.QKeyEvent(event.type(), Qt.Key_Down, event.modifiers()) # Remap 'K' to 'Up' elif key == Qt.Key_K: event = QtGui.QKeyEvent(event.type(), Qt.Key_Up, event.modifiers()) # Remap 'L' to 'Right' elif key == Qt.Key_L: event = QtGui.QKeyEvent(event.type(), Qt.Key_Right, event.modifiers()) # Re-read the event key to take the remappings into account key = event.key() if key == Qt.Key_Up: idxs = widget.selectedIndexes() rows = [idx.row() for idx in idxs] if len(rows) == 1 and rows[0] == 0: # The cursor is at the beginning of the line. # If we have selection then simply reset the cursor. # Otherwise, emit a signal so that the parent can # change focus. widget.up.emit() elif key == Qt.Key_Space: widget.space.emit() result = self.Base.keyPressEvent(widget, event) # Let others hook in here before we change the indexes widget.index_about_to_change.emit() # Automatically select the first entry when expanding a directory if (key == Qt.Key_Right and was_collapsed and widget.isExpanded(index)): index = widget.moveCursor(widget.MoveDown, event.modifiers()) widget.setCurrentIndex(index) # Process non-root entries with valid parents only. elif key == Qt.Key_Left and index.parent().isValid(): # File entries have rowCount() == 0 if widget.model().itemFromIndex(index).rowCount() == 0: widget.setCurrentIndex(index.parent()) # Otherwise, do this for collapsed directories only elif was_collapsed: widget.setCurrentIndex(index.parent()) # If it's a movement key ensure we have a selection elif key in (Qt.Key_Left, Qt.Key_Up, Qt.Key_Right, Qt.Key_Down): # Try to select the first item if the model index is invalid item = self.selected_item() if item is None or not index.isValid(): index = widget.model().index(0, 0, QtCore.QModelIndex()) if index.isValid(): widget.setCurrentIndex(index) return result
def desktop_size(): desk = desktop() rect = desk.screenGeometry(QtGui.QCursor().pos()) return (rect.width(), rect.height())
def mouseMoveEvent(self, event): """ Determine if the current movement is a drag. If it is, convert it into a QDrag. If the drag ends inside the tab bar, emit an onMoveTabSignal. If the drag ends outside the tab bar, emit an onDetachTabSignal. :param event: a mouse move event. """ # Determine if the current movement is detected as a drag if not self.drag_start_pos.isNull() and ( (event.pos() - self.drag_start_pos).manhattanLength() < QtWidgets.QApplication.startDragDistance()): self.drag_initiated = True # If the current movement is a drag initiated by the left button if (event.buttons() & QtCore.Qt.LeftButton) and self.drag_initiated: # Stop the move event finish_move_event = QtGui.QMouseEvent(QtCore.QEvent.MouseMove, event.pos(), QtCore.Qt.NoButton, QtCore.Qt.NoButton, QtCore.Qt.NoModifier) QtWidgets.QTabBar.mouseMoveEvent(self, finish_move_event) # Convert the move event into a drag drag = QtGui.QDrag(self) mime_data = QtCore.QMimeData() drag.setMimeData(mime_data) if PYQT4: pixmap = QtGui.QPixmap.grabWindow( self.parentWidget().currentWidget().winId()) else: app = QtWidgets.QApplication.instance() desktop = app.desktop() screen_number = desktop.screenNumber( self.parentWidget().currentWidget()) screen = app.screens()[screen_number] # Create the appearance of dragging the tab content pixmap = QtGui.QScreen.grabWindow( screen, self.parentWidget().currentWidget().winId()) target_pixmap = QtGui.QPixmap(pixmap.size()) target_pixmap.fill(QtCore.Qt.transparent) painter = QtGui.QPainter(target_pixmap) painter.setOpacity(0.85) painter.drawPixmap(0, 0, pixmap) painter.end() drag.setPixmap(target_pixmap) # Initiate the drag drop_action = drag.exec_(QtCore.Qt.MoveAction | QtCore.Qt.CopyAction) # For Linux: Here, drag.exec_() will not return MoveAction on Linux. So it # must be set manually if self.drag_end_pos.x() != 0 and self.drag_end_pos.y() != 0: drop_action = QtCore.Qt.MoveAction # If the drag completed outside of the tab bar, detach the tab and move # the content to the current cursor position if drop_action == QtCore.Qt.IgnoreAction: event.accept() self.onDetachTabSignal.emit( self.tabAt(self.drag_start_pos), self.mouse_cursor.pos()) # Else if the drag completed inside the tab bar, move the selected tab to the new position elif drop_action == QtCore.Qt.MoveAction: if not self.drag_end_pos.isNull(): event.accept() self.onMoveTabSignal.emit( self.tabAt(self.drag_start_pos), self.tabAt(self.drag_end_pos)) else: QtWidgets.QTabBar.mouseMoveEvent(self, event)
def inverted(color): return QtGui.QColor(*[255 - v for v in color.getRgb()])
def hoverLeaveEvent(self, event): # ... or switch back to standard color if self.active is False: self.setBrush(QtGui.QBrush(QtGui.QColor(0, 0, 0, 128)))
def setToInactiveColor(self): # change background color self.active = False self.setBrush(QtGui.QBrush(QtGui.QColor(0, 0, 0, 128)))
def __init__(self, parent: QtWidgets.QWidget, name: str = "", start_value: Optional[int] = None, max_value: int = 100, min_value: int = 0, font: Optional[QtGui.QFont] = None, scale: float = 1) -> None: QtWidgets.QGraphicsRectItem.__init__(self, parent) self.parent = parent self.name = name self.maxValue = max_value self.minValue = min_value self.format = "%.2f" self.setCursor(QtGui.QCursor(QtCore.Qt.OpenHandCursor)) self.setPen(QtGui.QPen(QtGui.QColor(255, 255, 255, 0))) self.text = QtWidgets.QGraphicsSimpleTextItem(self) if font is None: font = QtGui.QFont("", 11 / scale) else: font.setPointSize(int(11 / scale)) self.text.setFont(font) self.text.setPos(0, -23) self.text.setBrush(QtGui.QBrush(QtGui.QColor("white"))) self.sliderMiddel = QtWidgets.QGraphicsRectItem(self) self.sliderMiddel.setRect(QtCore.QRectF(0, 0, 100, 1)) self.sliderMiddel.setPen(QtGui.QPen(QtGui.QColor("white"))) path = QtGui.QPainterPath() path.addEllipse(-5, -5, 10, 10) self.slideMarker = QtWidgets.QGraphicsPathItem(path, self) self.slideMarker.setBrush(QtGui.QBrush(QtGui.QColor(255, 0, 0, 255))) self.setRect(QtCore.QRectF(-5, -5, 110, 10)) self.dragged = False self.value = (self.maxValue + self.minValue) * 0.5 if start_value is not None: self.value = start_value self.start_value = self.value self.setValue(self.value)
import copy import math from qtpy import QtCore from qtpy import QtGui import labelpoints.utils # TODO(unknown): # - [opt] Store paths instead of creating new ones at each paint. R, G, B = SHAPE_COLOR = 0, 255, 0 # green DEFAULT_LINE_COLOR = QtGui.QColor(R, G, B, 128) # bf hovering DEFAULT_FILL_COLOR = QtGui.QColor(R, G, B, 128) # hovering DEFAULT_SELECT_LINE_COLOR = QtGui.QColor(255, 255, 255) # selected DEFAULT_SELECT_FILL_COLOR = QtGui.QColor(R, G, B, 155) # selected DEFAULT_VERTEX_FILL_COLOR = QtGui.QColor(R, G, B, 255) # hovering DEFAULT_HVERTEX_FILL_COLOR = QtGui.QColor(255, 255, 255, 255) # hovering class Shape(object): P_SQUARE, P_ROUND = 0, 1 MOVE_VERTEX, NEAR_VERTEX = 0, 1 # The following class variables influence the drawing of all shape objects. line_color = DEFAULT_LINE_COLOR fill_color = DEFAULT_FILL_COLOR select_line_color = DEFAULT_SELECT_LINE_COLOR select_fill_color = DEFAULT_SELECT_FILL_COLOR
def loading_dialog(self): # Loading dialog. dlg = QtWidgets.QDialog(None, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint) dlg.setWindowTitle("HELLO!") dlg.setWindowIcon(QtGui.QIcon('icon.png')) return dlg.show()
def __init__(self, path = None): # Base window options. super(Viewer, self).__init__() self.setWindowTitle("SlicerVR - CAPS") self.setWindowIcon(QtGui.QIcon('icon.png')) self.resize(900, 600) self.file = None self._file_name = None # Pipeline-specific "constants" (defaults manipulated through options pane). self.HEIGHT_IN_PIXELS = 1024 self.WIDTH_IN_PIXELS = 1024 self.IMAGE_ROWS = 8 self.IMAGE_COLS = 8 self.DESIRED_SERIES = "DTI1" self.STD_DEV_ACROSS_N_FRAMES = 10 self.slicer_dir = r"C:\Users\loush\AppData\Local\NA-MIC\Slicer 4.11.0-2020-04-01" self.exportRan = False self.stdRan = False self.high_hu = 2000 self.low_hu = -1024 # self.pix_label = TrackingLabel(self) self.pix_label = DicomWidget(self) # self.color_table = [QtWidgets.qRgb(i, i, i) for i in range(256)] scroll_area = QtWidgets.QScrollArea() scroll_area.setWidget(self.pix_label) # self.setCentralWidget(self.pix_label) self.setCentralWidget(scroll_area) # self.series_dock = QtWidgets.QDockWidget("Series", self) # self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.series_dock) self.file_dock = QtWidgets.QDockWidget("Images", self) self.file_dock.setFeatures(QtWidgets.QDockWidget.DockWidgetMovable) self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.file_dock) self.file_list = QtWidgets.QListWidget() self.file_list.itemSelectionChanged.connect(self.on_file_item_change) self.file_dock.setWidget(self.file_list) # self.series_list = QtWidgets.QListWidget() # self.studies_list.itemSelectionChanged.connect(self.on_study_item_change) # self.series_dock.setWidget(self.series_list) self.hu_label = QtWidgets.QLabel("No image") self.c_label = QtWidgets.QLabel("") self.cw_label = QtWidgets.QLabel("") self.x_label = QtWidgets.QLabel("") self.y_label = QtWidgets.QLabel("") self.z_label = QtWidgets.QLabel("") self.use_fractional_coordinates = True self.ij_label = QtWidgets.QLabel("") self._zoom_level = 1 self.mouse_x = -1 self.mouse_y = -1 self.statusBar().addPermanentWidget(self.cw_label) self.statusBar().addPermanentWidget(self.ij_label) self.statusBar().addPermanentWidget(self.x_label) self.statusBar().addPermanentWidget(self.y_label) self.statusBar().addPermanentWidget(self.z_label) self.statusBar().addPermanentWidget(self.hu_label) self.data = np.ndarray((512, 512), np.int8) self.update_cw() if os.path.isfile(path): self.load_files([path]) elif os.path.isdir(path): self.load_files(dicom_files_in_dir(path)) self.build_menu()
def __init__(self, context, parent=None): standard.Dialog.__init__(self, parent) self.context = context self.setWindowTitle(N_('git-cola')) # Top-most large icon logo_pixmap = icons.cola().pixmap(defs.huge_icon, defs.huge_icon) self.logo_label = QtWidgets.QLabel() self.logo_label.setPixmap(logo_pixmap) self.logo_label.setAlignment(Qt.AlignCenter) self.logo_text_label = qtutils.label(text=version.cola_version()) self.logo_text_label.setAlignment(Qt.AlignCenter) self.repodir = None if context.runtask: self.runtask = context.runtask else: self.runtask = context.runtask = qtutils.RunTask(parent=self) self.new_button = qtutils.create_button(text=N_('New...'), icon=icons.new()) self.open_button = qtutils.create_button(text=N_('Open...'), icon=icons.folder()) self.clone_button = qtutils.create_button(text=N_('Clone...'), icon=icons.cola()) self.close_button = qtutils.close_button() self.bookmarks_model = bookmarks_model = QtGui.QStandardItemModel() self.items = items = [] item = QtGui.QStandardItem(N_('Open...')) item.setEditable(False) item.setIcon(icons.open_directory()) bookmarks_model.appendRow(item) # The tab bar allows choosing between Folder and List mode self.tab_bar = QtWidgets.QTabBar() self.tab_bar.setMovable(False) self.tab_bar.addTab(icons.directory(), N_('Folder')) self.tab_bar.addTab(icons.three_bars(), N_('List')) # Bookmarks/"Favorites" and Recent are lists of {name,path: str} settings = context.settings bookmarks = settings.bookmarks recent = settings.recent all_repos = bookmarks + recent directory_icon = icons.directory() user_role = Qt.UserRole normalize = display.normalize_path paths = set([normalize(repo['path']) for repo in all_repos]) short_paths = display.shorten_paths(paths) self.short_paths = short_paths added = set() for repo in all_repos: path = normalize(repo['path']) if path in added: continue added.add(path) item = QtGui.QStandardItem(path) item.setEditable(False) item.setData(path, user_role) item.setIcon(directory_icon) item.setToolTip(path) item.setText(self.short_paths.get(path, path)) bookmarks_model.appendRow(item) items.append(item) selection_mode = QtWidgets.QAbstractItemView.SingleSelection self.bookmarks = bookmarks = QtWidgets.QListView() bookmarks.setSelectionMode(selection_mode) bookmarks.setModel(bookmarks_model) bookmarks.setViewMode(QtWidgets.QListView.IconMode) bookmarks.setResizeMode(QtWidgets.QListView.Adjust) bookmarks.setGridSize(make_size(defs.large_icon)) bookmarks.setIconSize(make_size(defs.medium_icon)) bookmarks.setDragEnabled(False) bookmarks.setWordWrap(True) self.tab_layout = qtutils.vbox(defs.no_margin, defs.no_spacing, self.tab_bar, self.bookmarks) self.logo_layout = qtutils.vbox( defs.no_margin, defs.spacing, self.logo_label, self.logo_text_label, defs.button_spacing, qtutils.STRETCH, ) self.button_layout = qtutils.hbox( defs.no_margin, defs.spacing, self.open_button, self.clone_button, self.new_button, qtutils.STRETCH, self.close_button, ) self.main_layout = qtutils.grid(defs.margin, defs.spacing) self.main_layout.addItem(self.logo_layout, 1, 1) self.main_layout.addItem(self.tab_layout, 1, 2) self.main_layout.addItem(self.button_layout, 2, 1, columnSpan=2) self.setLayout(self.main_layout) qtutils.connect_button(self.open_button, self.open_repo) qtutils.connect_button(self.clone_button, self.clone_repo) qtutils.connect_button(self.new_button, self.new_repo) qtutils.connect_button(self.close_button, self.reject) # Open the selected repository when "enter" is pressed. self.action_open_repo = qtutils.add_action(self, N_('Open'), self.open_selected_bookmark, *hotkeys.ACCEPT) # pylint: disable=no-member self.tab_bar.currentChanged.connect(self.tab_changed) self.bookmarks.activated.connect(self.open_bookmark) self.init_state(settings, self.resize_widget) self.setFocusProxy(self.bookmarks) self.bookmarks.setFocus() # Update the list mode list_mode = context.cfg.get('cola.startupmode', default='folder') self.list_mode = list_mode if list_mode == 'list': self.tab_bar.setCurrentIndex(1)
def __init__( self, parent, audio, index, codec, available_audio_encoders, title="", language="", profile="", outdex=None, enabled=True, original=False, first=False, last=False, codecs=(), channels=2, all_info=None, ): self.loading = True super(Audio, self).__init__(parent) self.parent = parent self.audio = audio self.setFixedHeight(60) self.original = original self.outdex = index if self.original else outdex self.first = first self.track_name = title self.profile = profile self.last = last self.index = index self.codec = codec self.codecs = codecs self.channels = channels self.available_audio_encoders = available_audio_encoders self.widgets = Box( track_number=QtWidgets.QLabel( f"{index}:{self.outdex}" if enabled else "❌"), title=QtWidgets.QLineEdit(title), audio_info=QtWidgets.QLabel(audio), up_button=QtWidgets.QPushButton(QtGui.QIcon(up_arrow_icon), ""), down_button=QtWidgets.QPushButton(QtGui.QIcon(down_arrow_icon), ""), enable_check=QtWidgets.QCheckBox(t("Enabled")), dup_button=QtWidgets.QPushButton(QtGui.QIcon(copy_icon), ""), delete_button=QtWidgets.QPushButton(QtGui.QIcon(black_x_icon), ""), language=QtWidgets.QComboBox(), downmix=QtWidgets.QComboBox(), convert_to=None, convert_bitrate=None, ) self.widgets.up_button.setStyleSheet(no_border) self.widgets.down_button.setStyleSheet(no_border) self.widgets.dup_button.setStyleSheet(no_border) self.widgets.delete_button.setStyleSheet(no_border) if all_info: self.widgets.audio_info.setToolTip(all_info.to_yaml()) downmix_options = [ "mono", "stereo", "2.1 / 3.0", "3.1 / 4.0", "4.1 / 5.0", "5.1 / 6.0", "6.1 / 7.0", "7.1 / 8.0", ] self.widgets.language.addItems(["No Language Set"] + language_list) self.widgets.language.setMaximumWidth(110) if language: try: lang = Lang(language).name except InvalidLanguageValue: pass else: if lang in language_list: self.widgets.language.setCurrentText(lang) self.widgets.language.currentIndexChanged.connect(self.page_update) self.widgets.title.setFixedWidth(150) self.widgets.title.textChanged.connect(self.page_update) self.widgets.audio_info.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding) self.widgets.downmix.addItems([t("No Downmix")] + downmix_options[:channels - 2]) self.widgets.downmix.currentIndexChanged.connect(self.update_downmix) self.widgets.downmix.setCurrentIndex(0) self.widgets.downmix.setDisabled(True) self.widgets.enable_check.setChecked(enabled) self.widgets.enable_check.toggled.connect(self.update_enable) self.widgets.dup_button.clicked.connect(lambda: self.dup_me()) self.widgets.dup_button.setFixedWidth(20) self.widgets.delete_button.clicked.connect(lambda: self.del_me()) self.widgets.delete_button.setFixedWidth(20) self.widgets.track_number.setFixedWidth(20) label = QtWidgets.QLabel(f"{t('Title')}: ") self.widgets.title.setFixedWidth(150) title_layout = QtWidgets.QHBoxLayout() title_layout.addWidget(label) title_layout.addWidget(self.widgets.title) grid = QtWidgets.QGridLayout() grid.addLayout(self.init_move_buttons(), 0, 0) grid.addWidget(self.widgets.track_number, 0, 1) grid.addWidget(self.widgets.audio_info, 0, 2) grid.addLayout(title_layout, 0, 3) # grid.addWidget(self.widgets.title, 0, 4) grid.addLayout(self.init_conversion(), 0, 5) grid.addWidget(self.widgets.downmix, 0, 6) grid.addWidget(self.widgets.language, 0, 7) right_button_start_index = 8 if not original: spacer = QtWidgets.QLabel() spacer.setFixedWidth(63) grid.addWidget(spacer, 0, right_button_start_index) grid.addWidget(self.widgets.delete_button, 0, right_button_start_index + 1) else: grid.addWidget(self.widgets.enable_check, 0, right_button_start_index) grid.addWidget(self.widgets.dup_button, 0, right_button_start_index + 1) self.setLayout(grid) self.loading = False
def labelValidator(): return QtGui.QRegExpValidator(QtCore.QRegExp(r"^[^ \t].+"), None)
def setToActiveColor(self): # change background color self.active = True self.setBrush(QtGui.QBrush(QtGui.QColor(255, 255, 255, 128)))
def hoverEnterEvent(self, event) -> None: self.setBrush(QtGui.QBrush(QtGui.QColor(128, 128, 128, 128)))
def hoverEnterEvent(self, event): # if not active highlight on mouse over if self.active is False: self.setBrush(QtGui.QBrush(QtGui.QColor(128, 128, 128, 128)))
def hoverLeaveEvent(self, event) -> None: self.setBrush(QtGui.QBrush(QtGui.QColor(0, 0, 0, 128)))
def __init__(self, config=None, filename=None, output=None): # see labelme/config/default_config.yaml for valid configuration if config is None: config = get_config() self._config = config super(MainWindow, self).__init__() self.setWindowTitle(__appname__) # Whether we need to save or not. self.dirty = False self._noSelectionSlot = False # Main widgets and related state. self.labelDialog = LabelDialog( parent=self, labels=self._config['labels'], sort_labels=self._config['sort_labels'], show_text_field=self._config['show_label_text_field'], ) self.labelList = LabelQListWidget() self.lastOpenDir = None self.labelList.itemActivated.connect(self.labelSelectionChanged) self.labelList.itemSelectionChanged.connect(self.labelSelectionChanged) self.labelList.itemDoubleClicked.connect(self.editLabel) # Connect to itemChanged to detect checkbox changes. self.labelList.itemChanged.connect(self.labelItemChanged) self.labelList.setDragDropMode( QtWidgets.QAbstractItemView.InternalMove) self.labelList.setParent(self) listLayout = QtWidgets.QVBoxLayout() listLayout.setContentsMargins(0, 0, 0, 0) self.editButton = QtWidgets.QToolButton() self.editButton.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) listLayout.addWidget(self.editButton) # 0, Qt.AlignCenter) listLayout.addWidget(self.labelList) self.labelListContainer = QtWidgets.QWidget() self.labelListContainer.setLayout(listLayout) self.uniqLabelList = EscapableQListWidget() self.uniqLabelList.setToolTip( "Select label to start annotating for it. " "Press 'Esc' to deselect.") if self._config['labels']: self.uniqLabelList.addItems(self._config['labels']) self.uniqLabelList.sortItems() self.labelsdock = QtWidgets.QDockWidget(u'Label List', self) self.labelsdock.setObjectName(u'Label List') self.labelsdock.setWidget(self.uniqLabelList) self.dock = QtWidgets.QDockWidget('Polygon Labels', self) self.dock.setObjectName('Labels') self.dock.setWidget(self.labelListContainer) self.fileListWidget = QtWidgets.QListWidget() self.fileListWidget.itemSelectionChanged.connect( self.fileSelectionChanged) filelistLayout = QtWidgets.QVBoxLayout() filelistLayout.setContentsMargins(0, 0, 0, 0) filelistLayout.addWidget(self.fileListWidget) fileListContainer = QtWidgets.QWidget() fileListContainer.setLayout(filelistLayout) self.filedock = QtWidgets.QDockWidget(u'File List', self) self.filedock.setObjectName(u'Files') self.filedock.setWidget(fileListContainer) self.zoomWidget = ZoomWidget() self.colorDialog = ColorDialog(parent=self) self.canvas = self.labelList.canvas = Canvas() self.canvas.zoomRequest.connect(self.zoomRequest) scrollArea = QtWidgets.QScrollArea() scrollArea.setWidget(self.canvas) scrollArea.setWidgetResizable(True) self.scrollBars = { Qt.Vertical: scrollArea.verticalScrollBar(), Qt.Horizontal: scrollArea.horizontalScrollBar(), } self.canvas.scrollRequest.connect(self.scrollRequest) self.canvas.newShape.connect(self.newShape) self.canvas.shapeMoved.connect(self.setDirty) self.canvas.selectionChanged.connect(self.shapeSelectionChanged) self.canvas.drawingPolygon.connect(self.toggleDrawingSensitive) self.setCentralWidget(scrollArea) self.addDockWidget(Qt.RightDockWidgetArea, self.labelsdock) self.addDockWidget(Qt.RightDockWidgetArea, self.dock) self.addDockWidget(Qt.RightDockWidgetArea, self.filedock) self.filedock.setFeatures(QtWidgets.QDockWidget.DockWidgetFloatable) self.dockFeatures = (QtWidgets.QDockWidget.DockWidgetClosable | QtWidgets.QDockWidget.DockWidgetFloatable) self.dock.setFeatures(self.dock.features() ^ self.dockFeatures) # Actions action = functools.partial(newAction, self) shortcuts = self._config['shortcuts'] quit = action('&Quit', self.close, shortcuts['quit'], 'quit', 'Quit application') open_ = action('&Open', self.openFile, shortcuts['open'], 'open', 'Open image or label file') opendir = action('&Open Dir', self.openDirDialog, shortcuts['open_dir'], 'open', u'Open Dir') openNextImg = action('&Next Image', self.openNextImg, shortcuts['open_next'], 'next', u'Open Next') openPrevImg = action('&Prev Image', self.openPrevImg, shortcuts['open_prev'], 'prev', u'Open Prev') save = action('&Save', self.saveFile, shortcuts['save'], 'save', 'Save labels to file', enabled=False) saveAs = action('&Save As', self.saveFileAs, shortcuts['save_as'], 'save-as', 'Save labels to a different file', enabled=False) close = action('&Close', self.closeFile, shortcuts['close'], 'close', 'Close current file') color1 = action('Polygon &Line Color', self.chooseColor1, shortcuts['edit_line_color'], 'color_line', 'Choose polygon line color') color2 = action('Polygon &Fill Color', self.chooseColor2, shortcuts['edit_fill_color'], 'color', 'Choose polygon fill color') createMode = action('Create\nPolygo&ns', self.setCreateMode, shortcuts['create_polygon'], 'objects', 'Start drawing polygons', enabled=True) editMode = action('&Edit\nPolygons', self.setEditMode, shortcuts['edit_polygon'], 'edit', 'Move and edit polygons', enabled=True) delete = action('Delete\nPolygon', self.deleteSelectedShape, shortcuts['delete_polygon'], 'cancel', 'Delete', enabled=False) copy = action('&Duplicate\nPolygon', self.copySelectedShape, shortcuts['duplicate_polygon'], 'copy', 'Create a duplicate of the selected polygon', enabled=False) undoLastPoint = action('Undo last point', self.canvas.undoLastPoint, shortcuts['undo_last_point'], 'undo', 'Undo last drawn point', enabled=False) undo = action('Undo', self.undoShapeEdit, shortcuts['undo'], 'undo', 'Undo last add and edit of shape', enabled=False) hideAll = action('&Hide\nPolygons', functools.partial(self.togglePolygons, False), icon='eye', tip='Hide all polygons', enabled=False) showAll = action('&Show\nPolygons', functools.partial(self.togglePolygons, True), icon='eye', tip='Show all polygons', enabled=False) help = action('&Tutorial', self.tutorial, icon='help', tip='Show tutorial page') zoom = QtWidgets.QWidgetAction(self) zoom.setDefaultWidget(self.zoomWidget) self.zoomWidget.setWhatsThis( "Zoom in or out of the image. Also accessible with" " %s and %s from the canvas." % (fmtShortcut('%s,%s' % (shortcuts['zoom_in'], shortcuts['zoom_out'])), fmtShortcut("Ctrl+Wheel"))) self.zoomWidget.setEnabled(False) zoomIn = action('Zoom &In', functools.partial(self.addZoom, 10), shortcuts['zoom_in'], 'zoom-in', 'Increase zoom level', enabled=False) zoomOut = action('&Zoom Out', functools.partial(self.addZoom, -10), shortcuts['zoom_out'], 'zoom-out', 'Decrease zoom level', enabled=False) zoomOrg = action('&Original size', functools.partial(self.setZoom, 100), shortcuts['zoom_to_original'], 'zoom', 'Zoom to original size', enabled=False) fitWindow = action('&Fit Window', self.setFitWindow, shortcuts['fit_window'], 'fit-window', 'Zoom follows window size', checkable=True, enabled=False) fitWidth = action('Fit &Width', self.setFitWidth, shortcuts['fit_width'], 'fit-width', 'Zoom follows window width', checkable=True, enabled=False) # Group zoom controls into a list for easier toggling. zoomActions = (self.zoomWidget, zoomIn, zoomOut, zoomOrg, fitWindow, fitWidth) self.zoomMode = self.MANUAL_ZOOM self.scalers = { self.FIT_WINDOW: self.scaleFitWindow, self.FIT_WIDTH: self.scaleFitWidth, # Set to one to scale to 100% when loading files. self.MANUAL_ZOOM: lambda: 1, } edit = action('&Edit Label', self.editLabel, shortcuts['edit_label'], 'edit', 'Modify the label of the selected polygon', enabled=False) self.editButton.setDefaultAction(edit) shapeLineColor = action( 'Shape &Line Color', self.chshapeLineColor, icon='color-line', tip='Change the line color for this specific shape', enabled=False) shapeFillColor = action( 'Shape &Fill Color', self.chshapeFillColor, icon='color', tip='Change the fill color for this specific shape', enabled=False) labels = self.dock.toggleViewAction() labels.setText('Show/Hide Label Panel') # Lavel list context menu. labelMenu = QtWidgets.QMenu() addActions(labelMenu, (edit, delete)) self.labelList.setContextMenuPolicy(Qt.CustomContextMenu) self.labelList.customContextMenuRequested.connect( self.popLabelListMenu) # Store actions for further handling. self.actions = struct( save=save, saveAs=saveAs, open=open_, close=close, lineColor=color1, fillColor=color2, delete=delete, edit=edit, copy=copy, undoLastPoint=undoLastPoint, undo=undo, createMode=createMode, editMode=editMode, shapeLineColor=shapeLineColor, shapeFillColor=shapeFillColor, zoom=zoom, zoomIn=zoomIn, zoomOut=zoomOut, zoomOrg=zoomOrg, fitWindow=fitWindow, fitWidth=fitWidth, zoomActions=zoomActions, fileMenuActions=(open_, opendir, save, saveAs, close, quit), tool=(), editMenu=(edit, copy, delete, None, undo, undoLastPoint, None, color1, color2), menu=( createMode, editMode, edit, copy, delete, shapeLineColor, shapeFillColor, undo, undoLastPoint, ), onLoadActive=(close, createMode, editMode), onShapesPresent=(saveAs, hideAll, showAll), ) self.menus = struct( file=self.menu('&File'), edit=self.menu('&Edit'), view=self.menu('&View'), help=self.menu('&Help'), recentFiles=QtWidgets.QMenu('Open &Recent'), labelList=labelMenu, ) addActions(self.menus.file, (open_, opendir, self.menus.recentFiles, save, saveAs, close, None, quit)) addActions(self.menus.help, (help, )) addActions(self.menus.view, (labels, None, hideAll, showAll, None, zoomIn, zoomOut, zoomOrg, None, fitWindow, fitWidth)) self.menus.file.aboutToShow.connect(self.updateFileMenu) # Custom context menu for the canvas widget: addActions(self.canvas.menus[0], self.actions.menu) addActions(self.canvas.menus[1], (action('&Copy here', self.copyShape), action('&Move here', self.moveShape))) self.tools = self.toolbar('Tools') self.actions.tool = (open_, opendir, openNextImg, openPrevImg, save, None, createMode, copy, delete, editMode, undo, None, zoomIn, zoom, zoomOut, fitWindow, fitWidth) self.statusBar().showMessage('%s started.' % __appname__) self.statusBar().show() # Application state. self.image = QtGui.QImage() self.imagePath = None if self._config['auto_save'] and output is not None: warnings.warn('If `auto_save` argument is True, `output` argument ' 'is ignored and output filename is automatically ' 'set as IMAGE_BASENAME.json.') self.labeling_once = output is not None self.output = output self.recentFiles = [] self.maxRecent = 7 self.lineColor = None self.fillColor = None self.otherData = None self.zoom_level = 100 self.fit_window = False if filename is not None and os.path.isdir(filename): self.importDirImages(filename, load=False) else: self.filename = filename # XXX: Could be completely declarative. # Restore application settings. self.settings = QtCore.QSettings('labelme', 'labelme') # FIXME: QSettings.value can return None on PyQt4 self.recentFiles = self.settings.value('recentFiles', []) or [] size = self.settings.value('window/size', QtCore.QSize(600, 500)) position = self.settings.value('window/position', QtCore.QPoint(0, 0)) self.resize(size) self.move(position) # or simply: # self.restoreGeometry(settings['window/geometry'] self.restoreState( self.settings.value('window/state', QtCore.QByteArray())) self.lineColor = QtGui.QColor( self.settings.value('line/color', Shape.line_color)) self.fillColor = QtGui.QColor( self.settings.value('fill/color', Shape.fill_color)) Shape.line_color = self.lineColor Shape.fill_color = self.fillColor # Populate the File menu dynamically. self.updateFileMenu() # Since loading the file may take some time, # make sure it runs in the background. if self.filename is not None: self.queueEvent(functools.partial(self.loadFile, self.filename)) # Callbacks: self.zoomWidget.valueChanged.connect(self.paintCanvas) self.populateModeActions()
def SetToActiveColor(self): self.active = True self.setBrush(QtGui.QBrush(QtGui.QColor(204, 228, 247, 255))) self.setPen(QtGui.QPen(QtGui.QColor(0, 84, 153)))
def loadFile(self, filename=None): """Load the specified file, or the last opened file if None.""" # changing fileListWidget loads file if (filename in self.imageList and self.fileListWidget.currentRow() != self.imageList.index(filename)): self.fileListWidget.setCurrentRow(self.imageList.index(filename)) return self.resetState() self.canvas.setEnabled(False) if filename is None: filename = self.settings.value('filename', '') filename = str(filename) if not QtCore.QFile.exists(filename): self.errorMessage('Error opening file', 'No such file: <b>%s</b>' % filename) return False # assumes same name, but json extension self.status("Loading %s..." % os.path.basename(str(filename))) label_file = os.path.splitext(filename)[0] + '.json' if QtCore.QFile.exists(label_file) and \ LabelFile.isLabelFile(label_file): try: self.labelFile = LabelFile(label_file) # FIXME: PyQt4 installed via Anaconda fails to load JPEG # and JSON encoded images. # https://github.com/ContinuumIO/anaconda-issues/issues/131 if QtGui.QImage.fromData(self.labelFile.imageData).isNull(): raise LabelFileError( 'Failed loading image data from label file.\n' 'Maybe this is a known issue of PyQt4 built on' ' Anaconda, and may be fixed by installing PyQt5.') except LabelFileError as e: self.errorMessage( 'Error opening file', "<p><b>%s</b></p>" "<p>Make sure <i>%s</i> is a valid label file." % (e, label_file)) self.status("Error reading %s" % label_file) return False self.imageData = self.labelFile.imageData self.imagePath = os.path.join(os.path.dirname(label_file), self.labelFile.imagePath) self.lineColor = QtGui.QColor(*self.labelFile.lineColor) self.fillColor = QtGui.QColor(*self.labelFile.fillColor) self.otherData = self.labelFile.otherData else: # Load image: # read data first and store for saving into label file. self.imageData = read(filename, None) if self.imageData is not None: # the filename is image not JSON self.imagePath = filename self.labelFile = None image = QtGui.QImage.fromData(self.imageData) if image.isNull(): formats = [ '*.{}'.format(fmt.data().decode()) for fmt in QtGui.QImageReader.supportedImageFormats() ] self.errorMessage( 'Error opening file', '<p>Make sure <i>{0}</i> is a valid image file.<br/>' 'Supported image formats: {1}</p>'.format( filename, ','.join(formats))) self.status("Error reading %s" % filename) return False self.image = image self.filename = filename self.canvas.loadPixmap(QtGui.QPixmap.fromImage(image)) if self.labelFile: self.loadLabels(self.labelFile.shapes) self.setClean() self.canvas.setEnabled(True) self.adjustScale(initial=True) self.paintCanvas() self.addRecentFile(self.filename) self.toggleActions(True) self.status("Loaded %s" % os.path.basename(str(filename))) return True
def SetToInactiveColor(self): self.active = False self.setBrush(QtGui.QBrush(QtGui.QColor(255, 255, 255, 128))) self.setPen(QtGui.QPen(QtGui.QColor(0, 0, 0)))
def rgb(r, g, b): color = QtGui.QColor() color.setRgb(r, g, b) return color
def hoverEnterEvent(self, event): if self.active is False: self.setBrush( QtGui.QBrush(QtGui.QColor(255, 255, 255, 128 + 128 / 2)))
def font(string): qfont = QtGui.QFont() qfont.fromString(string) return qfont
def hoverLeaveEvent(self, event): if self.active is False: self.setBrush(QtGui.QBrush(QtGui.QColor(255, 255, 255, 128)))
def test_workspace(self, config): bg = QtGui.QBrush(QtGui.QColor('#aabbcc')) config.writeValue('Workspace/Background', bg) assert config.workspaceBackground() == bg
def getColor(self): return QtGui.QColor("white")
def cmd_line(): """the setup.py entry point for ``pyNastranGUI``""" # this fixes the icon shown in the windows taskbar to be the custom one (not the python one) if sys.platform == 'win32': myappid = 'pynastran.pynastrangui.%s' % (pyNastran.__version__ ) # arbitrary string ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid) from qtpy.QtWidgets import QApplication app = QApplication(sys.argv) if 0: try: import qtmodern.styles except ImportError: pass else: qtmodern.styles.dark(app) #app.setStyle('Fusion') #app.setStyle('WindowsXP') #if 0: #import qtpy.QtGui as QtGui #import qtpy.QtCore as QtCore #palette = QtGui.QPalette() #palette.setColor(QtGui.QPalette.Window, QtGui.QColor(53,53,53)) #palette.setColor(QtGui.QPalette.WindowText, QtCore.Qt.white) #palette.setColor(QtGui.QPalette.Base, QtGui.QColor(15,15,15)) #palette.setColor(QtGui.QPalette.AlternateBase, QtGui.QColor(53,53,53)) #palette.setColor(QtGui.QPalette.ToolTipBase, QtCore.Qt.white) #palette.setColor(QtGui.QPalette.ToolTipText, QtCore.Qt.white) #palette.setColor(QtGui.QPalette.Text, QtCore.Qt.white) #palette.setColor(QtGui.QPalette.Button, QtGui.QColor(53,53,53)) #palette.setColor(QtGui.QPalette.ButtonText, QtCore.Qt.white) #palette.setColor(QtGui.QPalette.BrightText, QtCore.Qt.red) #palette.setColor(QtGui.QPalette.Highlight, QtGui.QColor(142,45,197).lighter()) #palette.setColor(QtGui.QPalette.HighlightedText, QtCore.Qt.black) #app.setPalette(palette) if 0: import qtpy.QtGui as QtGui import qtpy.QtCore as QtCore from qtpy.QtGui import QPalette, QColor darkPalette = QtGui.QPalette() darkPalette.setColor(QPalette.WindowText, QColor(180, 180, 180)) darkPalette.setColor(QPalette.Button, QColor(53, 53, 53)) darkPalette.setColor(QPalette.Light, QColor(180, 180, 180)) darkPalette.setColor(QPalette.Midlight, QColor(90, 90, 90)) darkPalette.setColor(QPalette.Dark, QColor(35, 35, 35)) darkPalette.setColor(QPalette.Text, QColor(180, 180, 180)) darkPalette.setColor(QPalette.BrightText, QColor(180, 180, 180)) darkPalette.setColor(QPalette.ButtonText, QColor(180, 180, 180)) darkPalette.setColor(QPalette.Base, QColor(42, 42, 42)) darkPalette.setColor(QPalette.Window, QColor(53, 53, 53)) darkPalette.setColor(QPalette.Shadow, QColor(20, 20, 20)) darkPalette.setColor(QPalette.Highlight, QColor(42, 130, 218)) darkPalette.setColor(QPalette.HighlightedText, QColor(180, 180, 180)) darkPalette.setColor(QPalette.Link, QColor(56, 252, 196)) darkPalette.setColor(QPalette.AlternateBase, QColor(66, 66, 66)) darkPalette.setColor(QPalette.ToolTipBase, QColor(53, 53, 53)) darkPalette.setColor(QPalette.ToolTipText, QColor(180, 180, 180)) # disabled darkPalette.setColor(QPalette.Disabled, QPalette.WindowText, QColor(127, 127, 127)) darkPalette.setColor(QPalette.Disabled, QPalette.Text, QColor(127, 127, 127)) darkPalette.setColor(QPalette.Disabled, QPalette.ButtonText, QColor(127, 127, 127)) darkPalette.setColor(QPalette.Disabled, QPalette.Highlight, QColor(80, 80, 80)) darkPalette.setColor(QPalette.Disabled, QPalette.HighlightedText, QColor(127, 127, 127)) app.setPalette(darkPalette) QApplication.setOrganizationName("pyNastran") QApplication.setOrganizationDomain(pyNastran.__website__) QApplication.setApplicationName("pyNastran") QApplication.setApplicationVersion(pyNastran.__version__) inputs = get_inputs() #inputs['app'] = app MainWindow(inputs) app.exec_()
def setColor(self, color): # apply color self.text.setBrush(QtGui.QBrush(color))