def get_manager_button(self): """Returns QToolButton for managing the toolbar""" button = QToolButton(self) button.setText("Add/remove toolbar icons") button.setMenu(ToolbarManagerMenu(self)) button.setIcon(Icon.menu_manager) button.setFixedWidth(button.height() / 3) button.setPopupMode(QToolButton.InstantPopup) return button
class ToolOptionsPad(QWidget): """ An on-canvas toolbox widget. I'm dubbing widgets that 'float' on top of the canvas '(lily) pads' for the time being :) """ def __init__(self, mdiArea): super(ToolOptionsPad, self).__init__(mdiArea) self.setObjectName("toolOptionsPad") # self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.setWindowFlags( Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint ) self.setLayout(QVBoxLayout()) self.layout().setContentsMargins(4,4,4,4) # Members to hold a borrowed widget and it's original parent docker for returning self.widget = None self.widgetDocker = None self.container = ToolOptionsContainer() # Visibility toggle self.btnHide = QToolButton() self.btnHide.setIcon(Application.icon("light_visible")) self.btnHide.setIconSize(QSize(12,12)) self.btnHide.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum) self.btnHide.clicked.connect(self.toggleWidgetVisible) self.btnHide.setStyleSheet(""" QToolButton { background-color: #80000000; border: none; border-radius: 4px; } QToolButton:checked { background-color: #aa306fa8; } QToolButton:hover { background-color: #1c1c1c; } QToolButton:pressed { background-color: #53728e; } """) self.layout().addWidget(self.btnHide)#, 0, Qt.AlignRight) def closeEvent(self, e): """Since the plugins works by borrowing the actual docker widget we need to ensure its returned upon closing the pad""" self.returnDocker() return super().closeEvent(e) def paintEvent(self, e): """Needed to resize the Pad if the user decides to change the icon size of the toolbox""" self.adjustToView() return super().paintEvent(e) def borrowDocker(self, docker): """Borrow a docker widget from Krita's existing list of dockers and returns True. Returns False if invalid widget was passed. """ # Does requested widget exist? if isinstance(docker, QDockWidget) and docker.widget(): # Return any previous widget to its original docker self.returnDocker() self.widgetDocker = docker self.widget = docker.widget() # Because I'm forced to use "setFixedSize" to resize the tool options # it needs to be put in a container, otherwise it's going to break if/when # returned to its original docker. Manipulate the container; not the widget. self.container = ToolOptionsContainer() self.container.layout().addWidget(self.widget) self.layout().addWidget(self.container, 0, Qt.AlignRight) self.adjustToView() return True return False def returnDocker(self): """Return the borrowed docker to it's original QDockWidget""" # Ensure there's a widget to return if self.widget: self.widgetDocker.setWidget(self.widget) self.widget = None self.widgetDocker = None def adjustToView(self): """Adjust the position and size of the Pad to that of the active View.""" view = self.activeView() if view: self.resizeToView() # Resize first because the x-position is dependant on correct width. # pos = self.parentWidget().mapFromGlobal(view.mapToGlobal(QPoint(view.width() - self.parentWidget().width(), 0))) # Move to top of QMdiArea. Only suitable for 'AdjustToSubwindows' mode. pos = self.parentWidget().mapFromGlobal(view.mapToGlobal(QPoint(view.width() - self.width(), 0))) # Move to top left corner of current view. Hacky, but works! self.move(pos) def resizeToView(self): # The Tool Options widget is a nightmare to resize :) """Resize the Pad to an appropriate size that fits within the subwindow.""" view = self.activeView() if view and self.widget.isVisible(): # We start with the tool options sizeHint as a goal size and then # shrink it down if necessary to fit inside the view. containerSize = self.widget.widget().sizeHint() # I don't like all these magic numbers (And repeteition) but I honestly don't know what they # correspond to either. Margins, I suppose, but then why is one of the numbers 14 # when the margins are all 4? if view.height() < containerSize.height() + self.btnHide.height() + 14: containerSize.setHeight(view.height() - self.btnHide.height() - 14) if view.width() < containerSize.width() + 8: containerSize.setWidth(view.width() - 8) self.container.setFixedSize(containerSize) # Once the tool options container is an appropriate size, resize the # Pad widget to it's appropriate sizes padSize = self.sizeHint() if view.height() < padSize.height(): padSize.setHeight(view.height()) if view.width() < padSize.width(): padSize.setWidth(view.width()) self.setFixedSize(padSize) elif not self.widget.isVisible(): # Resize the widget to the size of the button + some extra height for the hidden widget I guess? # I just don't know what these numbers are, or why I can't use the # button's own sizeHint. The result also varies if something else # about the layout varies. self.setFixedSize(23, 54) def activeView(self): """Get the View widget of the active subwindow.""" subWin = self.parentWidget().activeSubWindow() if subWin: for child in subWin.children(): if 'view' in child.objectName(): # Grab the View from the active tab/sub-window return child def toggleWidgetVisible(self, value=None): if not value: value = not self.widget.isVisible() self.widget.setVisible(value) self.resizeToView()
class HomeRecommendedItem(QWidget, fc_home_recommended_item): """ This class represents a HomeRecommendedItem widget which is shown on the home page. This widget can either show a channel or a torrent. """ def __init__(self, parent): QWidget.__init__(self, parent) fc_home_recommended_item.__init__(self) self.setupUi(self) self.show_torrent = True self.torrent_info = None self.channel_info = None self.download_uri = None self.dialog = None # Create the category label, shown on cells that display a torrent on the home page self.category_label = QLabel(self) self.category_label.setFixedHeight(24) self.category_label.setSizePolicy( QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)) self.category_label.setStyleSheet(""" border: 2px solid white; border-radius: 12px; background-color: transparent; color: white; padding-left: 4px; padding-right: 4px; font-weight: bold; """) self.category_label.move(QPoint(6, 6)) self.category_label.show() # Create the dark overlay and download button over the thumbnail on hover self.dark_overlay = QWidget(self) self.dark_overlay.setStyleSheet( "background-color: rgba(0, 0, 0, 0.65);") self.dark_overlay.hide() self.download_button = QToolButton(self) self.download_button.setFixedSize(QSize(40, 40)) self.download_button.setStyleSheet(""" QToolButton { background-color: transparent; border: 2px solid white; border-radius: 20px; } QToolButton::hover { border: 2px solid #B5B5B5; } """) self.download_button.setIcon(QIcon(get_image_path('downloads.png'))) self.download_button.setIconSize(QSize(18, 18)) self.download_button.clicked.connect(self.on_download_button_clicked) self.download_button.hide() def on_download_button_clicked(self): if not self.torrent_info: return self.download_uri = (u"magnet:?xt=urn:btih:%s&dn=%s" % (self.torrent_info["infohash"], self.torrent_info['name'])).encode('utf-8') self.window().start_download_from_uri(self.download_uri) def update_with_torrent(self, torrent): if not torrent: return self.show_torrent = True self.torrent_info = torrent self.thumbnail_widget.initialize(torrent["name"], HOME_ITEM_FONT_SIZE) self.main_label.setText(torrent["name"]) self.category_label.setText(torrent["category"].lower() if ( "category" in torrent and torrent["category"]) else 'other') self.category_label.adjustSize() self.category_label.setHidden(False) self.setCursor(Qt.ArrowCursor) self.detail_label.setText("Size: " + format_size(torrent.get("size", 0))) def update_with_channel(self, channel): if not channel: return self.show_torrent = False self.channel_info = channel self.thumbnail_widget.initialize(channel["name"], HOME_ITEM_FONT_SIZE) self.main_label.setText(channel["name"]) self.detail_label.setText("%d torrents" % channel["torrents"]) self.category_label.setHidden(True) self.setCursor(Qt.PointingHandCursor) def enterEvent(self, _): if self.show_torrent: self.dark_overlay.resize(self.thumbnail_widget.size()) self.dark_overlay.show() self.download_button.move( (self.thumbnail_widget.width() - self.download_button.width()) / 2, (self.thumbnail_widget.height() - self.download_button.height()) / 2) self.download_button.show() def leaveEvent(self, _): self.dark_overlay.hide() self.download_button.hide()
class HomeRecommendedItem(QWidget, fc_home_recommended_item): """ This class represents a HomeRecommendedItem widget which is shown on the home page. This widget can either show a channel or a torrent. """ def __init__(self, parent): QWidget.__init__(self, parent) fc_home_recommended_item.__init__(self) self.setupUi(self) self.show_torrent = True self.torrent_info = None self.channel_info = None self.download_uri = None self.dialog = None # Create the category label, shown on cells that display a torrent on the home page self.category_label = QLabel(self) self.category_label.setFixedHeight(24) self.category_label.setSizePolicy(QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)) self.category_label.setStyleSheet(""" border: 2px solid white; border-radius: 12px; background-color: transparent; color: white; padding-left: 4px; padding-right: 4px; font-weight: bold; """) self.category_label.move(QPoint(6, 6)) self.category_label.show() # Create the dark overlay and download button over the thumbnail on hover self.dark_overlay = QWidget(self) self.dark_overlay.setStyleSheet("background-color: rgba(0, 0, 0, 0.65);") self.dark_overlay.hide() self.download_button = QToolButton(self) self.download_button.setFixedSize(QSize(40, 40)) self.download_button.setStyleSheet(""" QToolButton { background-color: transparent; border: 2px solid white; border-radius: 20px; } QToolButton::hover { border: 2px solid #B5B5B5; } """) self.download_button.setIcon(QIcon(get_image_path('downloads.png'))) self.download_button.setIconSize(QSize(18, 18)) self.download_button.clicked.connect(self.on_download_button_clicked) self.download_button.hide() def on_download_button_clicked(self): gui_settings = self.window().gui_settings self.download_uri = quote_plus((u"magnet:?xt=urn:btih:%s&dn=%s" % (self.torrent_info["infohash"], self.torrent_info['name'])).encode('utf-8')) if get_gui_setting(gui_settings, "ask_download_settings", True, is_bool=True): self.dialog = StartDownloadDialog(self.window().stackedWidget, self.download_uri, self.torrent_info["name"]) self.dialog.button_clicked.connect(self.on_start_download_action) self.dialog.show() else: self.window().perform_start_download_request(self.download_uri, get_gui_setting(gui_settings, "default_anonymity_enabled", True, is_bool=True), get_gui_setting(gui_settings, "default_safeseeding_enabled", True, is_bool=True), self.window().tribler_settings['downloadconfig']['saveas'], [], 0) def on_start_download_action(self, action): if action == 1: self.window().perform_start_download_request(self.download_uri, self.dialog.dialog_widget.anon_download_checkbox.isChecked(), self.dialog.dialog_widget.safe_seed_checkbox.isChecked(), self.dialog.dialog_widget.destination_input.text(), self.dialog.get_selected_files(), self.dialog.dialog_widget.files_list_view.topLevelItemCount()) self.dialog.request_mgr.cancel_request() self.dialog.setParent(None) self.dialog = None def update_with_torrent(self, torrent): self.show_torrent = True self.torrent_info = torrent self.thumbnail_widget.initialize(torrent["name"], HOME_ITEM_FONT_SIZE) self.main_label.setText(torrent["name"]) self.category_label.setText(torrent["category"]) self.category_label.adjustSize() self.category_label.setHidden(False) self.setCursor(Qt.ArrowCursor) self.detail_label.setText("Size: " + format_size(torrent["size"])) def update_with_channel(self, channel): self.show_torrent = False self.channel_info = channel self.thumbnail_widget.initialize(channel["name"], HOME_ITEM_FONT_SIZE) self.main_label.setText(channel["name"]) self.detail_label.setText("Updated " + pretty_date(channel["modified"])) self.category_label.setHidden(True) self.setCursor(Qt.PointingHandCursor) def enterEvent(self, _): if self.show_torrent: self.dark_overlay.resize(self.thumbnail_widget.size()) self.dark_overlay.show() self.download_button.move((self.thumbnail_widget.width() - self.download_button.width()) / 2, (self.thumbnail_widget.height() - self.download_button.height()) / 2) self.download_button.show() def leaveEvent(self, _): self.dark_overlay.hide() self.download_button.hide()
class HomeRecommendedItem(QWidget, fc_home_recommended_item): """ This class represents a HomeRecommendedItem widget which is shown on the home page. This widget can either show a channel or a torrent. """ def __init__(self, parent): QWidget.__init__(self, parent) fc_home_recommended_item.__init__(self) self.setupUi(self) self.show_torrent = True self.torrent_info = None self.channel_info = None self.download_uri = None self.dialog = None # Create the category label, shown on cells that display a torrent on the home page self.category_label = QLabel(self) self.category_label.setFixedHeight(24) self.category_label.setSizePolicy(QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Fixed)) self.category_label.setStyleSheet(""" border: 2px solid white; border-radius: 12px; background-color: transparent; color: white; padding-left: 4px; padding-right: 4px; font-weight: bold; """) self.category_label.move(QPoint(6, 6)) self.category_label.show() # Create the dark overlay and download button over the thumbnail on hover self.dark_overlay = QWidget(self) self.dark_overlay.setStyleSheet("background-color: rgba(0, 0, 0, 0.65);") self.dark_overlay.hide() self.download_button = QToolButton(self) self.download_button.setFixedSize(QSize(40, 40)) self.download_button.setStyleSheet(""" QToolButton { background-color: transparent; border: 2px solid white; border-radius: 20px; } QToolButton::hover { border: 2px solid #B5B5B5; } """) self.download_button.setIcon(QIcon(get_image_path('downloads.png'))) self.download_button.setIconSize(QSize(18, 18)) self.download_button.clicked.connect(self.on_download_button_clicked) self.download_button.hide() def on_download_button_clicked(self): if not self.torrent_info: return self.download_uri = (u"magnet:?xt=urn:btih:%s&dn=%s" % (self.torrent_info["infohash"], self.torrent_info['name'])).encode('utf-8') self.window().start_download_from_uri(self.download_uri) def update_with_torrent(self, torrent): if not torrent: return self.show_torrent = True self.torrent_info = torrent self.thumbnail_widget.initialize(torrent["name"], HOME_ITEM_FONT_SIZE) self.main_label.setText(torrent["name"]) self.category_label.setText(torrent["category"].lower()) self.category_label.adjustSize() self.category_label.setHidden(False) self.setCursor(Qt.ArrowCursor) self.detail_label.setText("Size: " + format_size(torrent["size"])) def update_with_channel(self, channel): if not channel: return self.show_torrent = False self.channel_info = channel self.thumbnail_widget.initialize(channel["name"], HOME_ITEM_FONT_SIZE) self.main_label.setText(channel["name"]) self.detail_label.setText("Updated " + pretty_date(channel["modified"])) self.category_label.setHidden(True) self.setCursor(Qt.PointingHandCursor) def enterEvent(self, _): if self.show_torrent: self.dark_overlay.resize(self.thumbnail_widget.size()) self.dark_overlay.show() self.download_button.move((self.thumbnail_widget.width() - self.download_button.width()) / 2, (self.thumbnail_widget.height() - self.download_button.height()) / 2) self.download_button.show() def leaveEvent(self, _): self.dark_overlay.hide() self.download_button.hide()
class CollapsibleSplitter(QSplitter): def __init__(self, parent, *args): super(CollapsibleSplitter, self).__init__(parent, *args) self.parent = parent self.setOpaqueResize(True) self.minDistanceToEdge = 20 # 到边缘的最小距离 self.splitterState = SplitterState.expanded self.bSplitterButton = False self.setHandleWidth(10) self.bExpandParentForm = False self.splitterMoved.connect(self.splitterMoveHandle) @pyqtProperty(bool) def SplitterButton(self): return self.bSplitterButton @SplitterButton.setter def SplitterButton(self, value): self.bSplitterButton = value @pyqtProperty(bool) def ExpandParentForm(self): return self.bExpandParentForm @ExpandParentForm.setter def ExpandParentForm(self, value): self.bExpandParentForm = value @pyqtProperty(SplitterState) def Stretch(self): return self.splitterState @Stretch.setter def Stretch(self, value): self.splitterState = value @pyqtProperty(Dock) def Dock(self): return self.dock @Dock.setter def Dock(self, value): self.dock = value @pyqtProperty(QWidget) def WidgetToHide(self): return self.widgetToHide @WidgetToHide.setter def WidgetToHide(self, value: QWidget): self.widgetToHide = value def showEvent(self, a0: QShowEvent) -> None: self.setupUi() def setupUi(self): self.handlePos = self.sizes() if self.widget(0).objectName() == self.widgetToHide.objectName(): self.otherWidget = self.widget(1) else: self.otherWidget = self.widget(0) self.hide_num = self.indexOf(self.widgetToHide) # 控制最小边缘距离 if self.dock == Dock.up or self.dock == Dock.down: self.setOrientation(Qt.Vertical) self.widgetToHide.setMinimumHeight(self.minDistanceToEdge) self.otherWidget.setMinimumHeight(self.minDistanceToEdge) else: self.setOrientation(Qt.Horizontal) self.widgetToHide.setMinimumWidth(self.minDistanceToEdge) self.otherWidget.setMinimumWidth(self.minDistanceToEdge) self.widgetToHide.setMouseTracking(True) self.otherWidget.setMouseTracking(True) self.setMouseTracking(True) if self.splitterState == SplitterState.collapsed: self.handleSplitterButton(SplitterState=SplitterState.expanded) if self.bSplitterButton: self.button = QToolButton(self.parentWidget()) self.button.clicked.connect( lambda: self.handleSplitterButton(self.splitterState)) def eventFilter(self, obj: QObject, event: QEvent): print(event.type()) if event.type() == QEvent.MouseMove: print("move") if event.type() == QEvent.KeyPress: print("key presss") if event.type() == QEvent.MouseButtonPress: print("press") return super().eventFilter(obj, event) def handleSplitterButton(self, SplitterState=SplitterState.expanded): # if not all(self.splitter.sizes()): # self.splitter.setSizes([1, 1]) self.setChildrenCollapsible(True) # print(self.sizes()) if SplitterState == SplitterState.expanded: self.handlePos = self.sizes() # 记下展开时的位置,如果再次展开回到这个位置 if self.bExpandParentForm: if self.dock == Dock.left or self.dock == Dock.right: self.hideLen = self.widgetToHide.width() self.window().resize(self.window().width() - self.hideLen, self.window().height()) else: self.hideLen = self.widgetToHide.height() self.window().resize(self.window().width(), self.window().height() - self.hideLen) if self.dock == Dock.up and self.dock == Dock.left: self.setSizes([0, 1]) else: self.setSizes([1, 0]) self.splitterState = SplitterState.collapsed else: if not self.bExpandParentForm: self.setSizes(self.handlePos) # 1, 0 else: if self.dock == Dock.up or self.dock == Dock.left: otherLen = self.sizes()[1] else: otherLen = self.sizes()[0] if self.dock == Dock.left or self.dock == Dock.right: # otherLen = self.sizes()[1] if hide_num == 0 else self.sizes()[0] self.window().resize(self.window().width() + self.hideLen, self.window().height()) else: self.window().resize(self.window().width(), self.window().height() + self.hideLen) if self.dock == Dock.up or self.dock == Dock.left: self.setSizes([self.hideLen, otherLen]) else: self.setSizes([otherLen, self.hideLen]) self.splitterState = SplitterState.expanded if self.bSplitterButton: self.setBtnIcon() self.setBtnPos() # if self.splitterState == SplitterState.collapsed: # self.setEnabled(False) # else: # self.setEnabled(True) def splitterMoveHandle(self, pos, index): if self.orientation() == Qt.Horizontal: w = self.width() else: w = self.height() if pos > self.minDistanceToEdge or pos < w - self.minDistanceToEdge: self.setChildrenCollapsible(False) # if self.splitterState == SplitterState.collapsed: # hide_num = self.indexOf(self.widgetToHide) # if self.Dock == Dock.up or self.Dock == Dock.left: # self.setSizes([1, 0]) if hide_num == 0 else self.setSizes([0, 1]) # else: # self.setSizes([0, 1]) if hide_num == 0 else self.setSizes([1, 0]) if self.bSplitterButton: self.setBtnPos() def createButton(self, width, height): self.button.setFocusPolicy(Qt.NoFocus) self.button.setMinimumSize(5, 15) self.button.resize(width, height) if self.dock == Dock.up: self.button.setArrowType(Qt.UpArrow) elif self.dock == Dock.down: self.button.setArrowType(Qt.DownArrow) elif self.dock == Dock.left: self.button.setArrowType(Qt.LeftArrow) elif self.dock == Dock.right: self.button.setArrowType(Qt.RightArrow) self.setBtnPos() def setBtnIcon(self): if self.button.arrowType() == Qt.LeftArrow: self.button.setArrowType(Qt.RightArrow) elif self.button.arrowType() == Qt.RightArrow: self.button.setArrowType(Qt.LeftArrow) elif self.button.arrowType() == Qt.UpArrow: self.button.setArrowType(Qt.DownArrow) elif self.button.arrowType() == Qt.DownArrow: self.button.setArrowType(Qt.UpArrow) def setBtnPos(self): if (self.dock == Dock.up and self.splitterState == SplitterState.expanded) or \ (self.dock == Dock.down and self.splitterState == SplitterState.collapsed): self.button.move( (self.widgetToHide.width() - self.button.width()) / 2, self.handle(1).pos().y() - self.button.height()) elif (self.dock == Dock.up and self.splitterState == SplitterState.collapsed) or \ (self.dock == Dock.down and self.splitterState == SplitterState.expanded): self.button.move( (self.widgetToHide.width() - self.button.width()) / 2, self.handle(1).pos().y() + self.handle(1).height()) elif (self.dock == Dock.right and self.splitterState == SplitterState.expanded) or \ (self.dock == Dock.left and self.splitterState == SplitterState.collapsed): self.button.move( self.handle(1).pos().x() + self.handle(1).width(), (self.widgetToHide.height() - self.button.height()) / 2) elif (self.dock == Dock.right and self.splitterState == SplitterState.collapsed) or \ (self.dock == Dock.left and self.splitterState == SplitterState.expanded): self.button.move( self.handle(1).pos().x() - self.button.width(), (self.widgetToHide.height() - self.button.height()) / 2) # def resizeEvent(self, a0: QResizeEvent): # self.resize(a0.size()) def createHandle(self): handle = SplitterHandle(self.orientation(), self) return handle
class PictureEditor(QWidget): modeChanged = pyqtSignal(EditMode) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.bkimage = QPixmap('./ui/png/tile.png') self.photo = None self.currentZoom = 1.0 self.offset = QPoint(0, 0) self.mode = EditMode.IDLE # overlays self.mesOverlay = MesOverlay(self) self.mesOverlay.doneCallBack = self._onMeasureDone self.roiOverlay = RoiOverlay(self) self.contOverlay = ContOverlay(self) self.contOverlay.freehandDone = self._onFreeHandDone self.overlays = [self.mesOverlay, self.roiOverlay, self.contOverlay] # eingebettete button self.btnContPlus = QToolButton(self) self.btnContPlus.setIcon(qta.icon('fa5s.plus', color='white')) self.btnContPlus.setStyleSheet("background-color: #19232D") self.btnContPlus.clicked.connect(self._onAddCountClicked) self.btnContPlus.hide() self.btnContMinus = QToolButton(self) self.btnContMinus.setIcon(qta.icon('fa5s.minus', color='white')) self.btnContMinus.setStyleSheet("background-color: #19232D") self.btnContMinus.clicked.connect(self._onRemoveCountClicked) self.btnContMinus.hide() self.btnFindCont = QPushButton('Find Contours', self) self.btnFindCont.clicked.connect(self._onFindContClicked) self.btnFindCont.hide() mngr = QtGui.qApp.sessionManager mngr.contourChanged.connect(self.updateContour) self.setMouseTracking(True) self.show() def setPhoto(self, photo, roi=None): self.mesOverlay.reset() self.photo = photo if roi is not None: if roi.isValid(): self.roiOverlay.imageRoi = roi else: w = photo.width() h = photo.height() self.roiOverlay.imageRoi = QRect(w / 4, h / 4, w / 2, h / 2) self.setMode(EditMode.ROI) else: self.update() def setMode(self, mode): if mode == self.mode: return newoverlay = self.getOverlay(mode) oldoverlay = self.getOverlay(self.mode) if oldoverlay is not None: oldoverlay.leave() if newoverlay is not None: newoverlay.enter() self.btnContPlus.hide() self.btnContMinus.hide() self.btnFindCont.setVisible(mode == EditMode.ROI) self.mode = mode self.modeChanged.emit(mode) self.update() @pyqtSlot(QPolygonF) def updateContour(self, cont): self.contOverlay.contour = cont self.update() def paintEvent(self, event): painter = QPainter() painter.begin(self) crc = self.rect() painter.fillRect(crc, QBrush(self.bkimage)) painter.setRenderHint(QPainter.Antialiasing) painter.setRenderHint(QPainter.HighQualityAntialiasing) if self.photo is not None: srcrect = self.photo.rect() destrect = self.transform().mapRect(srcrect) painter.drawPixmap(destrect, self.photo, srcrect) painter.fillRect(crc, QBrush(QColor(0, 0, 0, 40))) if self.mode == EditMode.IDLE: # alle duerfen zeichen for overlay in self.overlays: overlay.render(painter) else: self.getOverlay(self.mode).render(painter) painter.end() def event(self, event): proc = False overlay = self.getOverlay(self.mode) if overlay is not None: if overlay.routeEvent(event): proc = True if self.mode == EditMode.ROI: # update pos von fund contour button imroi = self.roiOverlay.imageRoi.normalized() br = self.transform().map(imroi.bottomRight()) self.btnFindCont.move(br.x() - self.btnFindCont.width(), br.y() + 8) if proc is True: return True else: return super().event(event) def mousePressEvent(self, event): if event.button() == Qt.MiddleButton: self._mousePressedPos = event.pos() - self.offset def mouseMoveEvent(self, event): if event.buttons() & Qt.MiddleButton: self.offset = event.pos() - self._mousePressedPos self.update() def wheelEvent(self, event): if (event.angleDelta().y() > 0) and self.currentZoom < 3.0: fct = 1.10 elif self.currentZoom > 1.0: fct = 1 / 1.10 else: fct = 1.0 self.currentZoom = self.currentZoom * fct self.update() def transform(self) -> QTransform: if self.photo is not None: srcrc = self.photo.rect() destrc = self.rect() trfshift = _translate(srcrc, destrc, self.offset) trfscale = _scale(srcrc, destrc, self.currentZoom) return trfscale * trfshift else: return QTransform() def _onMeasureDone(self): overlay = self.mesOverlay mngr = QtGui.qApp.sessionManager dlg = uic.loadUi('./ui/mesauredistdialog.ui') dlg.lineEdit.setValidator(QtGui.QIntValidator(0, 10000)) res = dlg.exec_() if res == QDialog.Accepted and len(dlg.lineEdit.text()) > 0: overlay.lengthText = dlg.lineEdit.text() + 'mm' mngr.ppmm = overlay.lineLength() / float(dlg.lineEdit.text()) if dlg.btnAcc.isChecked(): mngr.sizeFlags = session.SizeFlags.ACCURATELY elif dlg.btnLessAcc.isChecked(): mngr.sizeFlags = session.SizeFlags.LESS_ACCURATE elif dlg.btnInAcc.isChecked(): mngr.sizeFlags = session.SizeFlags.INACCURATE else: mngr.sizeFlags = session.SizeFlags.UNKNOWN else: mngr.ppmm = None mngr.sizeFlags = session.SizeFlags.UNKNOWN overlay.reset() self.setMode(EditMode.IDLE) def _onFreeHandDone(self, mousePos): offs = 10 h = self.btnContPlus.height() self.btnContMinus.move(mousePos.x() + offs, mousePos.y() + offs - h) self.btnContPlus.move(mousePos.x() + offs, mousePos.y() + offs) self.btnContPlus.show() self.btnContMinus.show() def _onAddCountClicked(self): sm = QtGui.qApp.sessionManager sm.addForeground(self.contOverlay.freeHandPath) self.contOverlay.freeHandPath.clear() self.btnContPlus.hide() self.btnContMinus.hide() self.update() def _onRemoveCountClicked(self): sm = QtGui.qApp.sessionManager sm.removeForeground(self.contOverlay.freeHandPath) self.contOverlay.freeHandPath.clear() self.btnContPlus.hide() self.btnContMinus.hide() self.update() def _onFindContClicked(self): self.setMode(EditMode.FG) sm = QtGui.qApp.sessionManager sm.findForeground(self.roiOverlay.imageRoi) def getOverlay(self, mode): o = { EditMode.IDLE: None, EditMode.MEASURE: self.mesOverlay, EditMode.ROI: self.roiOverlay, EditMode.FG: self.contOverlay } return o[mode]