def _get_tool_bar(self, name, priority): if name is None: name = "User Plugins" priority = -1 if name not in self._all_tool_bars: tool_bar = QToolBar(name) tool_bar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) tool_bar.setMovable(False) tool_bar.setStyleSheet(""" QToolBar { icon-size: 32px; } QToolBar QToolButton { height: 48px; } """) self._all_tool_bars[name] = dict(widget=tool_bar, priority=int(priority), name=name) else: if self._all_tool_bars[name]['priority'] == 0: self._all_tool_bars[name]['priority'] = priority return self._all_tool_bars[name]['widget']
def __init__(self, tracker: Tracker) -> None: super().__init__() self.qttracker = QtTracker(tracker) self.bg_thread = QThread(self) self.qttracker.moveToThread(self.bg_thread) self.bg_thread.start() self.qttracker.start_recording() self.setCentralWidget(Controls(self.qttracker)) toolbar = QToolBar() self.addToolBar(toolbar) toolbar.setMovable(False) toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.new_action = QAction("New", self) self.new_action.setToolTip("Create a new file for tracking.") icon = self.style().standardIcon(QStyle.SP_FileIcon) self.new_action.setIcon(icon) self.new_action.triggered.connect(self.new_db) toolbar.addAction(self.new_action) self.load_action = QAction("Load", self) self.load_action.setToolTip("Load a existing file for tracking.") icon = self.style().standardIcon(QStyle.SP_DialogOpenButton) self.load_action.setIcon(icon) self.load_action.triggered.connect(self.load_db) toolbar.addAction(self.load_action)
class MainWindow(QMainWindow, Ui_MainWindow): def __init__(self, app_manager, *args, **kwargs): # class init super(MainWindow, self).__init__(*args, **kwargs) self.app = app_manager # Setup Ui self.setupUi(self) self.actions = WindowActions(self.app) self.toolbar = QToolBar('toolbar') self.addToolBar(self.toolbar) # Setup Ui self.setWindowTitle(self.app.app_name) self.setWindowIcon(self.app.ui.window_icon) self.toolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) # Setup actions self.actions.exit.triggered.connect(self.app.quit) # Setup menus self.menu_File.addAction(self.actions.exit) # Setup toolbar self.toolbar.addAction(self.actions.exit) # Helpers def bar_log(self, msg): self.statusBar().showMessage(msg)
def fill_layout(self): """Fill grid layout""" import qwt for fname in get_tests(qwt): self.add_test(fname) toolbar = QToolBar(self) all_act = QAction(self.get_std_icon("DialogYesButton"), "", self) all_act.setIconText("Run all tests") all_act.triggered.connect(lambda checked: run_all_tests(wait=False)) folder_act = QAction(self.get_std_icon("DirOpenIcon"), "", self) folder_act.setIconText("Open tests folder") open_test_folder = lambda checked: os.startfile(TEST_PATH) folder_act.triggered.connect(open_test_folder) about_act = QAction(self.get_std_icon("FileDialogInfoView"), "", self) about_act.setIconText("About") about_act.triggered.connect(self.about) for action in (all_act, folder_act, None, about_act): if action is None: toolbar.addSeparator() else: toolbar.addAction(action) toolbar.setToolButtonStyle(Qt.ToolButtonTextBesideIcon) self.addToolBar(toolbar)
class DataBrowser(QWidget): sigOpen = Signal(NonDBHeader) sigPreview = Signal(NonDBHeader) def __init__(self, browserview): super(DataBrowser, self).__init__() hbox = QHBoxLayout() vbox = QVBoxLayout() vbox.setContentsMargins(0, 0, 0, 0) vbox.setSpacing(0) hbox.setContentsMargins(0, 0, 0, 0) hbox.setSpacing(0) self.setContentsMargins(0, 0, 0, 0) self.browserview = browserview self.browserview.sigOpen.connect(self.sigOpen) self.browserview.sigPreview.connect(self.sigPreview) self.browserview.sigOpenExternally.connect(self.openExternally) self.browserview.sigURIChanged.connect(self.uri_to_text) self.toolbar = QToolBar() self.toolbar.addAction(QIcon(QPixmap(str(path("icons/up.png")))), "Move up directory", self.moveUp) # self.toolbar.addAction(QIcon(QPixmap(str(path('icons/filter.png')))), 'Filter') self.toolbar.addAction(QIcon(QPixmap(str(path("icons/refresh.png")))), "Refresh", self.hardRefreshURI) self.toolbar.setToolButtonStyle(Qt.ToolButtonIconOnly) self.URILineEdit = SearchLineEdit("", clearable=False) self.uri_to_text() hbox.addWidget(self.toolbar) hbox.addWidget(self.URILineEdit) vbox.addLayout(hbox) vbox.addWidget(self.browserview) self.setLayout(vbox) self.URILineEdit.textChanged.connect(self.softRefreshURI) self.URILineEdit.returnPressed.connect(self.softRefreshURI) # hard refresh self.URILineEdit.focusOutEvent = self.softRefreshURI # hard refresh self.hardRefreshURI() def text_to_uri(self): uri = parse.urlparse(self.URILineEdit.text()) self.browserview.model().uri = uri print("uri:", uri) return uri def uri_to_text(self): uri = self.browserview.model().uri text = parse.urlunparse(uri) self.URILineEdit.setText(text) return text def hardRefreshURI(self, *_, **__): self.text_to_uri() self.browserview.refresh() def moveUp(self): self.browserview.model().uri = parse.urlparse(str(Path(self.URILineEdit.text()).parent)) self.browserview.refresh() self.uri_to_text() def openExternally(self, uri): webbrowser.open(uri) softRefreshURI = hardRefreshURI
class TyphosSidebarItem(ptypes.ParameterItem): """ Class to display a Device or Tool in the sidebar """ def __init__(self, param, depth): super().__init__(param, depth) # Configure a QToolbar self.toolbar = QToolBar() self.toolbar.setToolButtonStyle(Qt.ToolButtonIconOnly) self.toolbar.setIconSize(QSize(15, 15)) # Setup the action to open the widget self.open_action = QAction(qta.icon('fa.square', color='green'), 'Open', self.toolbar) self.open_action.triggered.connect(self.open_requested) # Setup the action to embed the widget self.embed_action = QAction(qta.icon('fa.th-large', color='yellow'), 'Embed', self.toolbar) self.embed_action.triggered.connect(self.embed_requested) # Setup the action to hide the widget self.hide_action = QAction(qta.icon('fa.times-circle', color='red'), 'Close', self.toolbar) self.hide_action.triggered.connect(self.hide_requested) self.hide_action.setEnabled(False) # Add actions to toolbars self.toolbar.addAction(self.open_action) self.toolbar.addAction(self.hide_action) if self.param.embeddable: self.toolbar.insertAction(self.hide_action, self.embed_action) def open_requested(self, triggered): """Request to open display for sidebar item""" self.param.sigOpen.emit(self) self._mark_shown() def embed_requested(self, triggered): """Request to open embedded display for sidebar item""" self.param.sigEmbed.emit(self) self._mark_shown() def hide_requested(self, triggered): """Request to hide display for sidebar item""" self.param.sigHide.emit(self) self._mark_hidden() def _mark_shown(self): self.open_action.setEnabled(False) self.embed_action.setEnabled(False) self.hide_action.setEnabled(True) def _mark_hidden(self): self.open_action.setEnabled(True) self.embed_action.setEnabled(True) self.hide_action.setEnabled(False) def treeWidgetChanged(self): """Update the widget when add to a QTreeWidget""" super().treeWidgetChanged() tree = self.treeWidget() if tree is None: return tree.setItemWidget(self, 1, self.toolbar)
class MainWindow(QMainWindow): FIT_WINDOW, FIT_WIDTH, MANUAL_ZOOM = 0, 1, 2 def __init__(self, label_file=None): super(MainWindow, self).__init__() self.showMaximized() self.setWindowTitle("VTCC.Labelling") self.file_dirs = [] self.file_id = -1 self.labels = [] with open(label_file, 'r') as f: lines = f.read().splitlines() for label in lines: self.labels.append(label) # RIGHT DOCK self.label_dock = QDockWidget("Label List", self) self.label_list_widget = QListWidget(self) self.load_labels(label_file) self.label_dock.setWidget(self.label_list_widget) self.object_dock = QDockWidget("Object List", self) self.object_list_widget = QListWidget(self) self.object_list_widget.currentRowChanged.connect(self.change_object) self.object_dock.setWidget(self.object_list_widget) self.file_dock = QDockWidget("File List", self) self.file_list_widget = QListWidget(self) self.file_list_widget.currentRowChanged.connect(self.change_file) self.file_dock.setWidget(self.file_list_widget) self.addDockWidget(Qt.RightDockWidgetArea, self.label_dock) self.addDockWidget(Qt.RightDockWidgetArea, self.object_dock) self.addDockWidget(Qt.RightDockWidgetArea, self.file_dock) # MAIN CANVAS self.canvas = Canvas(self) self.canvas_area = QScrollArea() self.canvas_area.setWidget(self.canvas) self.canvas_area.setWidgetResizable(True) self.scrollBars = { Qt.Vertical: self.canvas_area.verticalScrollBar(), Qt.Horizontal: self.canvas_area.horizontalScrollBar(), } self.setCentralWidget(self.canvas_area) # LEFT DOCK self.open_action = QAction(QIcon('icons/open.png'), 'Open File', self) self.open_action.triggered.connect(self.open_file) self.open_action.setShortcut(QKeySequence("Ctrl+O")) self.open_dir_action = QAction(QIcon('icons/open.png'), 'Open Dir', self) self.open_dir_action.triggered.connect(self.open_dir) self.next_img_action = QAction(QIcon('icons/next.png'), 'Next Image', self) self.next_img_action.triggered.connect(self.next_img) self.next_img_action.setShortcut(QKeySequence("Right")) self.prev_img_action = QAction(QIcon('icons/prev.png'), 'Prev Image', self) self.prev_img_action.triggered.connect(self.prev_img) self.prev_img_action.setShortcut(QKeySequence("Left")) self.zoom_in_action = QAction(QIcon('icons/zoom-in.png'), 'Zoom In', self) self.zoom_in_action.triggered.connect(self.zoom_in) self.zoom_out_action = QAction(QIcon('icons/zoom-out.png'), 'Zoom Out', self) self.zoom_out_action.triggered.connect(self.zoom_out) self.zoom_org_action = QAction(QIcon('icons/fit-window.png'), 'Fit Window', self) self.zoom_org_action.triggered.connect(self.zoom_org) self.rectangle_action = QAction(QIcon('icons/objects.png'), 'New Rectangle', self) self.rectangle_action.triggered.connect(self.new_rectangle) self.auto_polygon_action = QAction(QIcon('icons/objects.png'), 'New Auto-Polygon', self) self.auto_polygon_action.triggered.connect(self.new_auto_polygon) self.polygon_action = QAction(QIcon('icons/objects.png'), 'New Polygon', self) self.polygon_action.triggered.connect(self.new_polygon) self.next_obj_action = QAction(QIcon('icons/next.png'), 'Next Object', self) self.next_obj_action.triggered.connect(self.canvas.next_obj) self.next_obj_action.setShortcut(QKeySequence("Down")) self.prev_obj_action = QAction(QIcon('icons/prev.png'), 'Prev Object', self) self.prev_obj_action.triggered.connect(self.canvas.prev_obj) self.prev_obj_action.setShortcut(QKeySequence("Up")) self.del_obj_action = QAction(QIcon('icons/delete.png'), 'Delete Object', self) self.del_obj_action.triggered.connect(self.canvas.del_obj) self.del_obj_action.setShortcut(QKeySequence("Del")) self.toolbar = QToolBar(self) self.toolbar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon) self.toolbar.addAction(self.open_action) self.toolbar.addAction(self.open_dir_action) self.toolbar.addAction(self.next_img_action) self.toolbar.addAction(self.prev_img_action) # self.toolbar.addAction(self.zoom_in_action) # self.toolbar.addAction(self.zoom_out_action) # self.toolbar.addAction(self.zoom_org_action) self.toolbar.addAction(self.rectangle_action) self.toolbar.addAction(self.auto_polygon_action) self.toolbar.addAction(self.polygon_action) self.toolbar.addAction(self.next_obj_action) self.toolbar.addAction(self.prev_obj_action) self.toolbar.addAction(self.del_obj_action) self.addToolBar(Qt.LeftToolBarArea, self.toolbar) 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, } def update_mode(self, mode_id): pass def change_object(self, row): if (row >= 0): self.canvas.cur_object = row self.canvas.repaint() def change_file(self, row): if (row >= 0): self.file_id = row self.canvas.load_file(self.file_dirs[self.file_id]) self.adjustScale(initial=True) def open_file(self): path = '.' if len(self.file_dirs) > 0: path = os.path.dirname(str(self.file_dirs[0])) formats = [ '*.{}'.format(fmt.data().decode()) for fmt in QImageReader.supportedImageFormats() ] filters = "Image files (%s)" % ' '.join(formats) file_dir = QFileDialog.getOpenFileName(self, \ "Choose Image file", path, filters)[0] self.file_dirs = [file_dir] self.import_files() def open_dir(self): targetDirPath = str( QFileDialog.getExistingDirectory( self, 'Open Directory', '.', QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)) self.file_dirs = [] for fmt in QImageReader.supportedImageFormats(): pattern = os.path.join(targetDirPath, "*." + fmt.data().decode()) self.file_dirs += glob.glob(pattern) self.import_files() def next_img(self): if (len(self.file_dirs) > 0): self.file_id = (self.file_id + 1) % len(self.file_dirs) self.canvas.load_file(self.file_dirs[self.file_id]) self.adjustScale(initial=True) self.file_list_widget.setCurrentRow(self.file_id) def prev_img(self): if (len(self.file_dirs) > 0): self.file_id = (self.file_id + len(self.file_dirs) - 1) % len( self.file_dirs) self.canvas.load_file(self.file_dirs[self.file_id]) self.adjustScale(initial=True) self.file_list_widget.setCurrentRow(self.file_id) def import_files(self): self.load_file_list() self.file_id = 0 self.canvas.load_file(self.file_dirs[0]) self.adjustScale(initial=True) self.file_list_widget.setCurrentRow(self.file_id) def load_labels(self, label_file): self.label_list_widget.clear() for label in self.labels: item = QListWidgetItem(label) self.label_list_widget.addItem(item) def load_object_list(self, objects): self.object_list_widget.clear() for obj in objects: item = QListWidgetItem(obj.label) self.object_list_widget.addItem(item) def load_file_list(self): self.file_list_widget.clear() for image_dir in self.file_dirs: if not QFile.exists(image_dir): continue item = QListWidgetItem(image_dir) item.setFlags(Qt.ItemIsEnabled | Qt.ItemIsSelectable) label_dir = os.path.splitext(image_dir)[0] + '.json' if QFile.exists(label_dir): item.setCheckState(Qt.Checked) else: item.setCheckState(Qt.Unchecked) self.file_list_widget.addItem(item) def scaleFitWindow(self): """Figure out the size of the pixmap to fit the main widget.""" e = 2.0 # So that no scrollbars are generated. w1 = self.centralWidget().width() - e h1 = self.centralWidget().height() - e a1 = w1 / h1 # Calculate a new scale value based on the pixmap's aspect ratio. w2 = self.canvas.pixmap.width() - 0.0 h2 = self.canvas.pixmap.height() - 0.0 a2 = w2 / h2 return w1 / w2 if a2 >= a1 else h1 / h2 def scaleFitWidth(self): # The epsilon does not seem to work too well here. w = self.centralWidget().width() - 2.0 return w / self.canvas.pixmap.width() def adjustScale(self, initial=False): value = self.scalers[self.FIT_WINDOW if initial else self.zoomMode]() self.canvas.rescale(value) def zoom_in(self): value = self.canvas.scale self.canvas.rescale(value * 1.1) def zoom_out(self): value = self.canvas.scale self.canvas.rescale(value * 0.9) def zoom_org(self): print(self.centralWidget().width(), self.centralWidget().height()) print(self.canvas.pixmap.width(), self.canvas.pixmap.height()) print(self.canvas.width(), self.canvas.height()) print(self.canvas_area.width(), self.canvas_area.height()) self.adjustScale(initial=True) def new_rectangle(self): self.canvas.points = [] self.canvas.mode = self.canvas.RECTANGLE def new_auto_polygon(self): self.canvas.points = [] self.canvas.mode = self.canvas.AUTO_POLYGON def new_polygon(self): self.canvas.points = [] self.canvas.mode = self.canvas.POLYGON