def __init__(self, parent, ancestor, rename_tabs=False, split_char='', split_index=0): QTabBar.__init__(self, parent) self.ancestor = ancestor # To style tabs on Mac if sys.platform == 'darwin': self.setObjectName('plugin-tab') # Dragging tabs self.__drag_start_pos = QPoint() self.setAcceptDrops(True) self.setUsesScrollButtons(True) self.setMovable(True) # Tab name editor self.rename_tabs = rename_tabs if self.rename_tabs: # Creates tab name editor self.tab_name_editor = EditTabNamePopup(self, split_char, split_index) else: self.tab_name_editor = None
def more_options_device_view(self, button): if "Disconnect" in button.text(): menu = QMenu("Menu", self) menu.addAction("Pair / Ping", self.ping_paired_device) menu.addAction("Attempt TCPIP on device", self.tcpip_paired_device) menu.addAction("Forget device", self.forget_paired_device) else: menu = QMenu("Menu", self) menu.addAction("Attempt TCPIP on device", self.tcpip_paired_device) menu.addAction("Attempt reconnection", self.ping_paired_device) menu.addAction("Refresh", self.refresh_devices) _, identifier = self.current_device_identifier() if platform.System.system() == "Linux" and identifier.count(".") >= 3: menu.addAction( "Add Desktop Shortcut to this device", self.create_desktop_shortcut_linux_os, ) menu.exec_( self.devices_view.mapToGlobal( QPoint( self.devices_view.visualItemRect(button).x() + 22, self.devices_view.visualItemRect(button).y() + 22, )))
def __activateStickyDrag(self, obj): """ This should be run every time the user clicks. Args: obj (QWidget / QItem --> DragWidget): Object to install all of the extra attrs on """ obj._cursor_pos = QCursor.pos() top_left = getTopLeftPos(obj) QCursor.setPos(top_left + QPoint(10, 10)) obj.setFocus() # set up drag time attrs obj.updateOrigValue() obj._calc_pos = QCursor.pos() obj._drag_STICKY = not obj._drag_STICKY obj._num_ticks = 0 obj._pixels_per_tick = self.pixelsPerTick() obj._value_per_tick = self.valuePerTick() # toggle cursor display if obj._drag_STICKY: obj.setCursor(Qt.BlankCursor)
def paintEvent(self, e): cr = self.contentsRect() painter = QPainter(self) painter.setClipRegion(e.region()) # if self.__data.isDown: # qDrawWinButton( # painter, 0, 0, self.width(), self.height(), self.palette(), True # ) painter.save() if self.__data.isDown: shiftSize = buttonShift(self) painter.translate(shiftSize.width(), shiftSize.height()) painter.setClipRect(cr) self.drawContents(painter) if not self.__data.icon.isNull(): iconRect = QRect(cr) iconRect.setX(iconRect.x() + self.margin()) if self.__data.itemMode != QwtLegendData.ReadOnly: iconRect.setX(iconRect.x() + BUTTONFRAME) iconRect.setSize(self.__data.icon.size()) iconRect.moveCenter(QPoint(iconRect.center().x(), cr.center().y())) painter.drawPixmap(iconRect, self.__data.icon) painter.restore()
def _calculate_position(self, at_line=None, at_point=None): """ Calculate a global point position `QPoint(x, y)`, for a given line, local cursor position, or local point. """ font = self.font() if at_point is not None: # Showing tooltip at point position cx, cy = at_point.x(), at_point.y() elif at_line is not None: # Showing tooltip at line cx = 5 line = at_line - 1 cursor = QTextCursor(self.document().findBlockByNumber(line)) cy = self.cursorRect(cursor).top() else: # Showing tooltip at cursor position cx, cy = self.get_coordinates('cursor') cy = cy - font.pointSize() / 2 # Calculate vertical delta # The needed delta changes with font size, so we use a power law if sys.platform == 'darwin': delta = int((font.pointSize() * 1.20) ** 0.98) + 4.5 elif os.name == 'nt': delta = int((font.pointSize() * 1.20) ** 1.05) + 7 else: delta = int((font.pointSize() * 1.20) ** 0.98) + 7 # delta = font.pointSize() + 5 # Map to global coordinates point = self.mapToGlobal(QPoint(cx, cy)) point = self.calculate_real_position(point) point.setY(point.y() + delta) return point
def _show_warning(self, new_shortcut='', action=None, row=0, message=''): """Creates and displays warning message when shortcut is already assigned. Parameters ---------- new_shortcut : str The new shortcut attempting to be set. action : Action Action that is already assigned with the shortcut. row : int Row in table where the shortcut is attempting to be set. message : str Message to be displayed in warning pop up. """ # Determine placement of warning message. delta_y = 105 delta_x = 10 global_point = self.mapToGlobal( QPoint( self._table.columnViewportPosition(self._shortcut_col) + delta_x, self._table.rowViewportPosition(row) + delta_y, )) # Create warning pop up and move it to desired position. self._warn_dialog = WarnPopup(text=message, ) self._warn_dialog.move(global_point) # Styling adjustments. self._warn_dialog.resize(250, self._warn_dialog.sizeHint().height()) self._warn_dialog._message.resize( 200, self._warn_dialog._message.sizeHint().height()) self._warn_dialog.exec_()
def doLayout(self, rect, testOnly): x = rect.x() y = rect.y() line_height = 0 for item in self.itemList: wid = item.widget() if wid is not None: space_x = self.spacing() + wid.style().layoutSpacing( QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Horizontal) space_y = self.spacing() + wid.style().layoutSpacing( QSizePolicy.PushButton, QSizePolicy.PushButton, Qt.Vertical) else: # wid = item.layout() space_x = self.spacing( ) # + wid.layoutSpacing(QSizePolicy.PushButton, QSizePolicy.PushButton, # Qt.Horizontal) space_y = self.spacing( ) # + wid.layoutSpacing(QSizePolicy.PushButton, QSizePolicy.PushButton, # Qt.Vertical) next_x = x + item.sizeHint().width() + space_x if next_x - space_x > rect.right() and line_height > 0: x = rect.x() y = y + line_height + space_y next_x = x + item.sizeHint().width() + space_x line_height = 0 if not testOnly: item.setGeometry(QRect(QPoint(x, y), item.sizeHint())) x = next_x line_height = max(line_height, item.sizeHint().height()) return y + line_height - rect.y()
def __init__(self, public): ''' Private data constructor Parameters ---------- public : FloatingDockContainer ''' self.public = public self.dock_container = None global _z_order_counter # TODO _z_order_counter += 1 self.z_order_index = _z_order_counter self.dock_manager = None self.dragging_state = DragState.inactive self.drag_start_mouse_position = QPoint() self.drop_container = None self.single_dock_area = None # For Linux, specifically (TODO - better split?) self.mouse_event_handler = None self.title_bar = None
def move_from(self, cur_pos_data: Tuple[float, float]) -> None: """ Calculate a new position based on the given starting position and self.newpixel transform and move the mouse cursor there. :param cur_pos_data: Current cursor position in data coordinates """ new_pos_data = self.clip(self.new_pixel(*cur_pos_data)) xdisp, ydisp = self.data_to_display.transform_point(new_pos_data) canvas = self.canvas dpi_ratio = canvas._dpi_ratio to_int = self.to_int xp = to_int(xdisp / dpi_ratio) yp = to_int((canvas.figure.bbox.height - ydisp) / dpi_ratio) # in the special case of just vertical/horizontal moves # use the original cursor position for the orthogonal coordinate # to avoid rounding errors and mouse jitter new_global_pos = canvas.mapToGlobal(QPoint(xp, yp)) cur_global_pos = QCursor.pos() if new_pos_data[0] == cur_pos_data[0]: new_global_pos.setX(cur_global_pos.x()) if new_pos_data[1] == cur_pos_data[1]: new_global_pos.setY(cur_global_pos.y()) QCursor.setPos(new_global_pos)
def show_data_downloader(self): """ Show the download data dialog. """ if self.data_downloader is None: self.data_downloader = WeatherStationDownloader( workdir=self._workdir) self.data_downloader.setWindowState(Qt.WindowNoState) self.data_downloader.show() # Center the data downloader window to the mainwindow. qr = self.data_downloader.frameGeometry() wp = self.frameGeometry().width() hp = self.frameGeometry().height() cp = self.mapToGlobal(QPoint(wp / 2, hp / 2)) qr.moveCenter(cp) self.data_downloader.move(qr.topLeft()) else: self.data_downloader.show() self.data_downloader.activateWindow() self.data_downloader.raise_() if self.data_downloader.windowState() == Qt.WindowMinimized: # Window is minimised. Restore it. self.data_downloader.setWindowState(Qt.WindowNoState)
def sidePlaceHolderRect(self, widget, side): widgetRect = widget.rect() parentSplitter = cast(widget.parentWidget(), QSplitter) if parentSplitter and parentSplitter.indexOf(widget) > 0: delta = parentSplitter.handleWidth( ) / 2 + self.rubberBandLineWidth / 2 if side == ToolWindowManager.TopOf and parentSplitter.orientation( ) == Qt.Vertical: return QRect( QPoint(widgetRect.left(), widgetRect.top() - delta), QSize(widgetRect.width(), self.rubberBandLineWidth)) elif side == ToolWindowManager.LeftOf and parentSplitter.orientation( ) == Qt.Horizontal: return QRect( QPoint(widgetRect.left() - delta, widgetRect.top()), QSize(self.rubberBandLineWidth, widgetRect.height())) if side == ToolWindowManager.TopOf: return QRect(QPoint(widgetRect.left(), widgetRect.top()), QSize(widgetRect.width(), self.rubberBandLineWidth)) elif side == ToolWindowManager.LeftOf: return QRect(QPoint(widgetRect.left(), widgetRect.top()), QSize(self.rubberBandLineWidth, widgetRect.height())) elif side == ToolWindowManager.BottomOf: return QRect( QPoint( widgetRect.left(), widgetRect.top() + widgetRect.height() - self.rubberBandLineWidth), QSize(widgetRect.width(), self.rubberBandLineWidth)) elif side == ToolWindowManager.RightOf: return QRect( QPoint( widgetRect.left() + widgetRect.width() - self.rubberBandLineWidth, widgetRect.top()), QSize(self.rubberBandLineWidth, widgetRect.height())) else: qWarning('invalid side') return QRect()
def show_list(self, completion_list, position): # Completions are handled differently for the Internal # console. if position is None: # Somehow the position was not saved. # Hope that the current position is still valid self.position = self.textedit.textCursor().position() elif self.textedit.textCursor().position() < position: # hide the text as we moved away from the position return else: self.position = position if not isinstance(completion_list[0], dict): self.is_internal_console = True self.completion_list = completion_list self.clear() icons_map = { CompletionItemKind.PROPERTY: 'attribute', CompletionItemKind.VARIABLE: 'attribute', CompletionItemKind.METHOD: 'method', CompletionItemKind.FUNCTION: 'function', CompletionItemKind.CLASS: 'class', CompletionItemKind.MODULE: 'module', CompletionItemKind.CONSTRUCTOR: 'method', CompletionItemKind.REFERENCE: 'attribute' } for completion in completion_list: if not self.is_internal_console: icon = icons_map.get(completion['kind'], 'no_match') self.addItem( QListWidgetItem(ima.icon(icon), completion['insertText'])) else: # This is used by the Internal console. self.addItem(QListWidgetItem(completion[0])) self.setCurrentRow(0) QApplication.processEvents(QEventLoop.ExcludeUserInputEvents) self.show() self.setFocus() self.raise_() # Retrieving current screen height desktop = QApplication.desktop() srect = desktop.availableGeometry(desktop.screenNumber(self)) screen_right = srect.right() screen_bottom = srect.bottom() point = self.textedit.cursorRect().bottomRight() point = self.textedit.calculate_real_position(point) point = self.textedit.mapToGlobal(point) # Computing completion widget and its parent right positions comp_right = point.x() + self.width() ancestor = self.parent() if ancestor is None: anc_right = screen_right else: anc_right = min([ancestor.x() + ancestor.width(), screen_right]) # Moving completion widget to the left # if there is not enough space to the right if comp_right > anc_right: point.setX(point.x() - self.width()) # Computing completion widget and its parent bottom positions comp_bottom = point.y() + self.height() ancestor = self.parent() if ancestor is None: anc_bottom = screen_bottom else: anc_bottom = min([ancestor.y() + ancestor.height(), screen_bottom]) # Moving completion widget above if there is not enough space below x_position = point.x() if comp_bottom > anc_bottom: point = self.textedit.cursorRect().topRight() point = self.textedit.mapToGlobal(point) point.setX(x_position) point.setY(point.y() - self.height()) if ancestor is not None: # Useful only if we set parent to 'ancestor' in __init__ point = ancestor.mapFromGlobal(point) self.move(point) if not self.is_internal_console: tooltip_point = QPoint(point) tooltip_point.setX(point.x() + self.width()) tooltip_point.setY(point.y() - (3 * self.height()) // 4) for completion in completion_list: completion['point'] = tooltip_point if to_text_string( to_text_string( self.textedit.get_current_word(completion=True))): # When initialized, if completion text is not empty, we need # to update the displayed list: self.update_current() # signal used for testing self.sig_show_completions.emit(completion_list)
def pixmap(self, size, mode, state): pm = QPixmap(size) pm.fill(Qt.transparent) self.paint(QPainter(pm), QRect(QPoint(0, 0), size), mode, state) return pm
def show_right_of_mouse(self, *args): pos = QCursor().pos() # mouse position szhint = self.sizeHint() pos -= QPoint(-14, szhint.height() / 4) self.move(pos) self.show()
def crosshair_pixmap(): """Create a cross cursor with white/black hollow square pixmap in the middle. For use as points cursor.""" size = 25 pixmap = QPixmap(QSize(size, size)) pixmap.fill(Qt.transparent) painter = QPainter(pixmap) # Base measures width = 1 center = 3 # Must be odd! rect_size = center + 2 * width square = rect_size + width * 4 pen = QPen(Qt.white, 1) pen.setJoinStyle(Qt.PenJoinStyle.MiterJoin) painter.setPen(pen) # # Horizontal rectangle painter.drawRect(0, (size - rect_size) // 2, size - 1, rect_size - 1) # Vertical rectangle painter.drawRect((size - rect_size) // 2, 0, rect_size - 1, size - 1) # Square painter.drawRect( (size - square) // 2, (size - square) // 2, square - 1, square - 1 ) pen = QPen(Qt.black, 2) pen.setJoinStyle(Qt.PenJoinStyle.MiterJoin) painter.setPen(pen) # # Square painter.drawRect( (size - square) // 2 + 2, (size - square) // 2 + 2, square - 4, square - 4, ) pen = QPen(Qt.black, 3) pen.setJoinStyle(Qt.PenJoinStyle.MiterJoin) painter.setPen(pen) # # # Horizontal lines mid_vpoint = QPoint(2, size // 2) painter.drawLine( mid_vpoint, QPoint(((size - center) // 2) - center + 1, size // 2) ) mid_vpoint = QPoint(size - 3, size // 2) painter.drawLine( mid_vpoint, QPoint(((size - center) // 2) + center + 1, size // 2) ) # # # Vertical lines mid_hpoint = QPoint(size // 2, 2) painter.drawLine( QPoint(size // 2, ((size - center) // 2) - center + 1), mid_hpoint ) mid_hpoint = QPoint(size // 2, size - 3) painter.drawLine( QPoint(size // 2, ((size - center) // 2) + center + 1), mid_hpoint ) painter.end() return pixmap
def mapSceneToCamera(self, sc_pt): px_pt = self.mapSceneToPixmap(sc_pt) return QPoint(px_pt.x() + self.settings.get('left', 0), px_pt.y() + self.settings.get('top', 0))
def set_pos(self, x, y): """ """ self.x = ceil(x) self.y = ceil(y) self.move(QPoint(self.x, self.y))
def set_pos(self, x, y): """ """ self.x = x self.y = y self.move(QPoint(x, y))
def mousePressEvent(self, event): """Reimplement Qt method""" if event.button() == Qt.LeftButton: self.__drag_start_pos = QPoint(event.pos()) QTabBar.mousePressEvent(self, event)
def test_class_func_selector(lsp_codeeditor, qtbot): code_editor, _ = lsp_codeeditor panel = code_editor.classfuncdropdown panel.setVisible(True) code_editor.toggle_automatic_completions(False) code_editor.set_text(text) with qtbot.waitSignal(code_editor.lsp_response_signal, timeout=30000): code_editor.document_did_change() # Wait a little bit before asking for symbols qtbot.wait(2000) with qtbot.waitSignal(code_editor.lsp_response_signal, timeout=30000): code_editor.request_symbols() # Wait for symbols info to arrive qtbot.wait(2000) class_names = [item['name'] for item in panel.classes] func_names = [item['name'] for item in panel.funcs] assert len(panel.classes) == 2 assert len(panel.funcs) == 6 assert 'SomeObject' in class_names assert 'SomeOtherObject' in class_names assert '__init__' in func_names assert 'nested_func' in func_names # Check line is followed for _ in range(7): qtbot.keyPress(code_editor, Qt.Key_Down) assert panel.class_cb.currentText() == 'SomeObject' assert panel.method_cb.currentText() == 'SomeObject.__init__' for _ in range(18): qtbot.keyPress(code_editor, Qt.Key_Down) assert panel.class_cb.currentText() == 'SomeOtherObject' assert (panel.method_cb.currentText() == 'SomeOtherObject.hello_3.nested_func') # Check go to line works for class selector qtbot.mouseClick(panel.class_cb, Qt.LeftButton, pos=QPoint(5, 5)) listview = panel.class_cb.findChild(QListView) qtbot.keyPress(listview, Qt.Key_Up) qtbot.keyPress(listview, Qt.Key_Return) qtbot.wait(1000) cursor = code_editor.textCursor() assert cursor.blockNumber() == 4 assert panel.method_cb.currentIndex() == 0 # Check go to line works for func selector panel.method_cb.setFocus() qtbot.mouseClick(panel.method_cb, Qt.LeftButton, pos=QPoint(5, 5)) listview = panel.method_cb.findChild(QListView) qtbot.keyPress(listview, Qt.Key_Down) qtbot.keyPress(listview, Qt.Key_Down) qtbot.keyPress(listview, Qt.Key_Return) qtbot.wait(1000) cursor = code_editor.textCursor() assert cursor.blockNumber() == 9 assert panel.class_cb.currentIndex() == 1 panel.setVisible(False) code_editor.toggle_automatic_completions(True)
def _calculate_drawing_points(self, x, y, w, h): return [QPoint(x, h / 2.0), QPoint(x, y), QPoint(w / 2.0, y)]
from qtpy.QtCore import QPoint import gc with napari.gui_qt(): viewer = napari.Viewer() viewer.add_image(np.random.random((10, 10))) viewer.add_image(np.random.random((10, 10))) gc.collect() # Check layout and layers list match after rearranging layers viewer.layers[:] = [viewer.layers[i] for i in (1, 0)] # Do another reorder and check layout and layers list match # after swapping layers again viewer.layers[:] = [viewer.layers[i] for i in (1, 0)] viewer.layers[:] = [viewer.layers[i] for i in (1, 0)] viewer.layers[1].selected = True viewer.layers[0].selected = True # viewer.layers[1].selected=False # viewer.layers[0].selected=False Event = collections.namedtuple('Event', field_names=['pos']) event = Event(pos=lambda: QPoint(10, 10)) viewer.window._qt_viewer.layers.mousePressEvent(event) viewer.window._qt_viewer.layers.mouseReleaseEvent(event) #viewer.window._qt_viewer.update() viewer.window.show() viewer.layers[0].visible = False viewer.layers[1].visible = False gc.collect(generation=1)
def mouseReleaseEvent(self, event): QToolTip.showText(self.mapToGlobal(QPoint(0, self.height())), self._tip_text)
def _get_viewport_center(self): return QPoint(self.viewport().width() // 2, self.viewport().height() // 2)
def context_menu_requested(self, event, right_click=False): """Custom context menu.""" if self.proxy_model is None: return self._menu = QMenu(self) left_click = not right_click index = self.currentIndex() model_index = self.proxy_model.mapToSource(index) row_data = self.source_model.row(model_index.row()) column = model_index.column() name = row_data[C.COL_NAME] # package_type = row_data[C.COL_PACKAGE_TYPE] versions = self.source_model.get_package_versions(name) current_version = self.source_model.get_package_version(name) action_version = row_data[C.COL_ACTION_VERSION] package_status = row_data[C.COL_STATUS] package_type = row_data[C.COL_PACKAGE_TYPE] remove_actions = bool(self.source_model.count_remove_actions()) install_actions = bool(self.source_model.count_install_actions()) update_actions = bool(self.source_model.count_update_actions()) if column in [C.COL_ACTION] and left_click: is_installable = self.source_model.is_installable(model_index) is_removable = self.source_model.is_removable(model_index) is_upgradable = self.source_model.is_upgradable(model_index) action_status = self.source_model.action_status(model_index) actions = [] action_unmark = create_action( self, _('Unmark'), triggered=lambda: self.set_action_status( model_index, C.ACTION_NONE, current_version)) action_install = create_action( self, _('Mark for installation'), toggled=lambda: self.set_action_status(model_index, C. ACTION_INSTALL)) action_update = create_action( self, _('Mark for update'), toggled=lambda: self.set_action_status(model_index, C. ACTION_UPDATE, None)) action_remove = create_action( self, _('Mark for removal'), toggled=lambda: self.set_action_status( model_index, C.ACTION_REMOVE, current_version)) version_actions = [] for version in reversed(versions): def trigger(model_index=model_index, action=C.ACTION_INSTALL, version=version): return lambda: self.set_action_status( model_index, status=action, version=version) if version == current_version: version_action = create_action( self, version, icon=QIcon(), triggered=trigger(model_index, C.ACTION_INSTALL, version)) if not is_installable: version_action.setCheckable(True) version_action.setChecked(True) version_action.setDisabled(True) elif version != current_version: if ((version in versions and versions.index(version)) > (current_version in versions and versions.index(current_version))): upgrade_or_downgrade_action = C.ACTION_UPGRADE else: upgrade_or_downgrade_action = C.ACTION_DOWNGRADE if is_installable: upgrade_or_downgrade_action = C.ACTION_INSTALL version_action = create_action( self, version, icon=QIcon(), triggered=trigger(model_index, upgrade_or_downgrade_action, version)) if action_version == version: version_action.setCheckable(True) version_action.setChecked(True) version_actions.append(version_action) install_versions_menu = QMenu( 'Mark for specific version ' 'installation', self) add_actions(install_versions_menu, version_actions) actions = [ action_unmark, action_install, action_update, action_remove ] actions += [None, install_versions_menu] # Disable firing of signals, while setting the checked status for ac in actions + version_actions: if ac: ac.blockSignals(True) if action_status == C.ACTION_NONE: action_unmark.setEnabled(False) action_install.setEnabled(is_installable) action_update.setEnabled(is_upgradable) action_remove.setEnabled(is_removable) if install_actions: # Invalidate remove and update if install actions selected action_update.setDisabled(True) action_remove.setDisabled(True) elif remove_actions: # Invalidate install/update if remove actions already action_install.setDisabled(True) action_update.setDisabled(True) elif update_actions: # Invalidate install/update if remove actions already action_install.setDisabled(True) action_remove.setDisabled(True) install_versions_menu.setDisabled(False) elif action_status == C.ACTION_INSTALL: action_unmark.setEnabled(True) action_install.setEnabled(False) action_install.setChecked(True) action_update.setEnabled(False) action_remove.setEnabled(False) elif action_status == C.ACTION_REMOVE: action_unmark.setEnabled(True) action_install.setEnabled(False) action_update.setEnabled(False) action_remove.setEnabled(False) action_remove.setChecked(True) elif action_status == C.ACTION_UPDATE: action_unmark.setEnabled(True) action_install.setEnabled(False) action_update.setEnabled(False) action_update.setChecked(True) action_remove.setEnabled(False) elif action_status in [C.ACTION_UPGRADE, C.ACTION_DOWNGRADE]: action_unmark.setEnabled(True) action_install.setEnabled(False) action_update.setEnabled(False) action_update.setChecked(False) action_remove.setEnabled(False) install_versions_menu.setEnabled(False) if package_status == C.NOT_INSTALLED: action_remove.setEnabled(False) action_update.setEnabled(False) if package_type == C.PIP_PACKAGE: action_unmark.setEnabled(False) action_install.setEnabled(False) action_update.setEnabled(False) action_remove.setEnabled(False) # Enable firing of signals, while setting the checked status for ac in actions + version_actions: if ac: ac.blockSignals(False) install_versions_menu.setDisabled(True) install_versions_menu.setEnabled( len(version_actions) > 1 and not remove_actions and not update_actions) elif right_click: license_ = row_data[C.COL_LICENSE] metadata = self.metadata_links.get(name, {}) pypi = metadata.get('pypi', '') home = metadata.get('home', '') dev = metadata.get('dev', '') docs = metadata.get('docs', '') q_pypi = QIcon(get_image_path('python.png')) q_home = QIcon(get_image_path('home.png')) q_docs = QIcon(get_image_path('conda_docs.png')) if 'git' in dev: q_dev = QIcon(get_image_path('conda_github.png')) elif 'bitbucket' in dev: q_dev = QIcon(get_image_path('conda_bitbucket.png')) else: q_dev = QIcon() if 'mit' in license_.lower(): lic = 'http://opensource.org/licenses/MIT' elif 'bsd' == license_.lower(): lic = 'http://opensource.org/licenses/BSD-3-Clause' else: lic = None actions = [] if license_ != '': actions.append( create_action(self, _('License: ' + license_), icon=QIcon(), triggered=lambda: self.open_url(lic))) actions.append(None) if pypi != '': actions.append( create_action(self, _('Python Package Index'), icon=q_pypi, triggered=lambda: self.open_url(pypi))) if home != '': actions.append( create_action(self, _('Homepage'), icon=q_home, triggered=lambda: self.open_url(home))) if docs != '': actions.append( create_action(self, _('Documentation'), icon=q_docs, triggered=lambda: self.open_url(docs))) if dev != '': actions.append( create_action(self, _('Development'), icon=q_dev, triggered=lambda: self.open_url(dev))) if actions and len(actions) > 1: # self._menu = QMenu(self) add_actions(self._menu, actions) if event.type() == QEvent.KeyRelease: rect = self.visualRect(index) global_pos = self.viewport().mapToGlobal(rect.bottomRight()) else: pos = QPoint(event.x(), event.y()) global_pos = self.viewport().mapToGlobal(pos) self._menu.popup(global_pos)
def mousePressEvent(self, event: QMouseEvent) -> None: super().mousePressEvent(event) self.lastPos = QPoint(event.pos())
def update_canvas(self): """ """ w, h = self.parent.size().width(), self.parent.size().height() self.path_full = QPainterPath() self.path_subtract = QPainterPath() self.path_decoration = QPainterPath() self.region_mask = QRegion(0, 0, w, h) self.path_full.addRect(0, 0, w, h) # Add the path if self.widgets is not None: for widget in self.widgets: temp_path = QPainterPath() # if widget is not found... find more general way to handle if widget is not None: widget.raise_() widget.show() geo = widget.frameGeometry() width, height = geo.width(), geo.height() point = widget.mapTo(self.parent, QPoint(0, 0)) x, y = point.x(), point.y() temp_path.addRect(QRectF(x, y, width, height)) temp_region = QRegion(x, y, width, height) if self.interaction_on: self.region_mask = self.region_mask.subtracted(temp_region) self.path_subtract = self.path_subtract.united(temp_path) self.path_current = self.path_full.subtracted(self.path_subtract) else: self.path_current = self.path_full if self.decoration is not None: for widget in self.decoration: temp_path = QPainterPath() widget.raise_() widget.show() geo = widget.frameGeometry() width, height = geo.width(), geo.height() point = widget.mapTo(self.parent, QPoint(0, 0)) x, y = point.x(), point.y() temp_path.addRect(QRectF(x, y, width, height)) temp_region_1 = QRegion(x - 1, y - 1, width + 2, height + 2) temp_region_2 = QRegion(x + 1, y + 1, width - 2, height - 2) temp_region = temp_region_1.subtracted(temp_region_2) if self.interaction_on: self.region_mask = self.region_mask.united(temp_region) self.path_decoration = self.path_decoration.united(temp_path) else: self.path_decoration.addRect(0, 0, 0, 0) # Add a decoration stroke around widget self.setMask(self.region_mask) self.update() self.repaint()
def move_to_bottom_right(self, offset=(8, 8)): """Position widget at the bottom right edge of the parent.""" if not self.parent(): return sz = self.parent().size() - self.size() - QSize(*offset) self.move(QPoint(sz.width(), sz.height()))
def test_range_indicator_alt_modifier_response(editor_bot, qtbot): """Test that the slider range indicator is visible while the alt key is held down while the cursor is over the editor, but outside of the scrollflag area. In addition, while the alt key is held down, mouse click events in the editor should be forwarded to the scrollfag area and should set the value of the editor vertical scrollbar.""" editor = editor_bot sfa = editor.scrollflagarea sfa._unit_testing = True vsb = editor.verticalScrollBar() editor.resize(600, 300) editor.show() # Set a long text in the editor and assert that the slider is visible. editor.set_text(long_code) qtbot.waitUntil(lambda: sfa.slider) # Set the cursor position to the center of the editor. w = editor.width() h = editor.height() qtbot.mousePress(editor, Qt.LeftButton, pos=QPoint(w // 2, h // 2)) # Hold the alt key and assert that the slider range indicator is visible. # Because it is not possible to simulate the action of holding the alt # key down in pytest-qt, this is done through a flag in the ScrollFlagArea # that is set to True when pressing the alt key and to false when releasing # it. This flag is only used for testing purpose. qtbot.keyPress(editor, Qt.Key_Alt) qtbot.waitUntil(lambda: sfa._range_indicator_is_visible) # While the alt key is pressed, click with the mouse in the middle of the # editor's height and assert that the editor vertical scrollbar has moved # to its middle range position. with qtbot.waitSignal(editor.sig_alt_left_mouse_pressed, raising=True): qtbot.mousePress(editor.viewport(), Qt.LeftButton, pos=QPoint(w // 2, h // 2), modifier=Qt.AltModifier) assert vsb.value() == (vsb.minimum() + vsb.maximum()) // 2 # While the alt key is pressed, click with the mouse at the top of the # editor's height and assert that the editor vertical scrollbar has moved # to its minimum position. with qtbot.waitSignal(editor.sig_alt_left_mouse_pressed, raising=True): qtbot.mousePress(editor.viewport(), Qt.LeftButton, pos=QPoint(w // 2, 1), modifier=Qt.AltModifier) assert vsb.value() == vsb.minimum() # While the alt key is pressed, click with the mouse at the bottom of the # editor's height and assert that the editor vertical scrollbar has moved # to its maximum position. with qtbot.waitSignal(editor.sig_alt_left_mouse_pressed, raising=True): qtbot.mousePress(editor.viewport(), Qt.LeftButton, pos=QPoint(w // 2, h - 1), modifier=Qt.AltModifier) assert vsb.value() == vsb.maximum() # Release the alt key and assert that the slider range indicator is # not visible. qtbot.keyRelease(editor, Qt.Key_Alt) qtbot.waitUntil(lambda: not sfa._range_indicator_is_visible, timeout=3000)
def update_position(self): """Update slider position.""" x = self.get_pos() - self.width() / 2 y = self.slider.handle_radius + 6 self.move(QPoint(x, -y) + self.slider.pos())