def SetData(self, pSize=None, dataLen=0, state="", waifuSize=None, waifuDataLen=0, waifuState="", waifuTick=0, isInit=False): self.epsLabel.setText("位置:{}/{}".format(self.parent().curIndex+1, self.parent().maxPic)) if pSize or isInit: if not pSize: pSize = QSize(0, 0) self.resolutionLabel.setText("分辨率:{}x{}".format(str(pSize.width()), str(pSize.height()))) if dataLen or isInit: self.sizeLabel.setText("大小: " + ToolUtil.GetDownloadSize(dataLen)) if waifuSize or isInit: if not waifuSize: waifuSize = QSize(0, 0) self.resolutionWaifu.setText("分辨率:{}x{}".format(str(waifuSize.width()), str(waifuSize.height()))) if waifuDataLen or isInit: self.sizeWaifu.setText("大小:" + ToolUtil.GetDownloadSize(waifuDataLen)) if state or isInit: self.stateLable.setText("状态:" + state) if waifuState or isInit: self.stateWaifu.setText("状态:" + waifuState) if waifuTick or isInit: self.tickLabel.setText("耗时:" + str(waifuTick) + "s") self.parent().MoveTool()
def initThumbs(self) -> None: framesize = self.parent.videoService.framesize() thumbsize = QSize( VideoService.config.thumbnails['TIMELINE'].height() * (framesize.width() / framesize.height()), VideoService.config.thumbnails['TIMELINE'].height()) positions, frametimes = [], [] thumbs = int( math.ceil( (self.rect().width() - (self.offset * 2)) / thumbsize.width())) for pos in range(thumbs): val = QStyle.sliderValueFromPosition( self.minimum(), self.maximum(), (thumbsize.width() * pos) - self.offset, self.rect().width() - (self.offset * 2)) positions.append(val) positions[0] = 1000 [ frametimes.append( self.parent.delta2QTime(msec).toString(self.parent.timeformat)) for msec in positions ] class ThumbWorker(QObject): completed = pyqtSignal(list) def __init__(self, settings: QSettings, media: str, times: list, size: QSize): super(ThumbWorker, self).__init__() self.settings = settings self.media = media self.times = times self.size = size @pyqtSlot() def generate(self): frames = list() [ frames.append( VideoService.captureFrame(self.settings, self.media, frame, self.size)) for frame in self.times ] self.completed.emit(frames) self.thumbsThread = QThread(self) self.thumbsWorker = ThumbWorker(self.parent.settings, self.parent.currentMedia, frametimes, thumbsize) self.thumbsWorker.moveToThread(self.thumbsThread) self.thumbsThread.started.connect(self.parent.sliderWidget.setLoader) self.thumbsThread.started.connect(self.thumbsWorker.generate) self.thumbsThread.finished.connect(self.thumbsThread.deleteLater, Qt.DirectConnection) self.thumbsWorker.completed.connect(self.buildTimeline) self.thumbsWorker.completed.connect(self.thumbsWorker.deleteLater, Qt.DirectConnection) self.thumbsWorker.completed.connect(self.thumbsThread.quit, Qt.DirectConnection) self.thumbsThread.start()
def _get_icon_rect(self, opt, text_rect): """Get a QRect for the icon to draw. Args: opt: QStyleOptionTab text_rect: The QRect for the text. Return: A QRect. """ icon_size = opt.iconSize if not icon_size.isValid(): icon_extent = self.pixelMetric(QStyle.PM_SmallIconSize) icon_size = QSize(icon_extent, icon_extent) icon_mode = (QIcon.Normal if opt.state & QStyle.State_Enabled else QIcon.Disabled) icon_state = (QIcon.On if opt.state & QStyle.State_Selected else QIcon.Off) # reserve space for favicon when tab bar is vertical (issue #1968) position = config.get('tabs', 'position') if (opt.icon.isNull() and position in [QTabWidget.East, QTabWidget.West] and config.get('tabs', 'show-favicons')): tab_icon_size = icon_size else: actual_size = opt.icon.actualSize(icon_size, icon_mode, icon_state) tab_icon_size = QSize( min(actual_size.width(), icon_size.width()), min(actual_size.height(), icon_size.height())) icon_rect = QRect(text_rect.left(), text_rect.top() + 1, tab_icon_size.width(), tab_icon_size.height()) icon_rect = self._style.visualRect(opt.direction, opt.rect, icon_rect) return icon_rect
def sizeHint(self): q = self.parentWidget() mw = q.style().pixelMetric(QStyle.PM_DockWidgetTitleMargin, None, q) fw = q.style().pixelMetric(QStyle.PM_DockWidgetFrameWidth, None, q) closeSize = QSize(0, 0) if self.closeButton: closeSize = self.closeButton.sizeHint() floatSize = QSize(0, 0) if self.floatButton: floatSize = self.floatButton.sizeHint() hideSize = QSize(0, 0) if self.collapseButton: hideSize = self.collapseButton.sizeHint() pinSize = QSize(0, 0) if self.pinButton: pinSize = self.pinButton.sizeHint() buttonHeight = max(max(closeSize.height(), floatSize.height()), hideSize.height(), pinSize.height()) + 2 buttonWidth = closeSize.width() + floatSize.width() + hideSize.width( ) + pinSize.width() titleFontMetrics = q.fontMetrics() fontHeight = titleFontMetrics.lineSpacing() + 2 * mw height = max(buttonHeight, fontHeight) width = buttonWidth + height + 4 * mw + 2 * fw if hasFeature(q, QDockWidget.DockWidgetVerticalTitleBar): width, height = height, width return QSize(width, height)
def __init__(self, manager: SoftwareManager, i18n: I18n, screen_size: QSize, tray, window: QWidget, parent: QWidget = None): super(SettingsWindow, self).__init__(parent=parent) self.setWindowTitle(i18n['settings'].capitalize()) self.setLayout(QVBoxLayout()) self.manager = manager self.i18n = i18n self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred) self.tray = tray self.window = window self.settings_model = self.manager.get_settings(screen_size.width(), screen_size.height()) tab_group = to_widget(self.settings_model, i18n) tab_group.setMinimumWidth(int(screen_size.width() / 3)) self.layout().addWidget(tab_group) action_bar = QToolBar() action_bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed) bt_close = QPushButton() bt_close.setText(self.i18n['close'].capitalize()) bt_close.clicked.connect(lambda: self.close()) action_bar.addWidget(bt_close) action_bar.addWidget(new_spacer()) bt_change = QPushButton() bt_change.setStyleSheet(css.OK_BUTTON) bt_change.setText(self.i18n['change'].capitalize()) bt_change.clicked.connect(self._save_settings) action_bar.addWidget(bt_change) self.layout().addWidget(action_bar)
def _get_icon_rect(self, opt, text_rect): """Get a QRect for the icon to draw. Args: opt: QStyleOptionTab text_rect: The QRect for the text. Return: A QRect. """ icon_size = opt.iconSize if not icon_size.isValid(): icon_extent = self.pixelMetric(QStyle.PM_SmallIconSize) icon_size = QSize(icon_extent, icon_extent) icon_mode = (QIcon.Normal if opt.state & QStyle.State_Enabled else QIcon.Disabled) icon_state = (QIcon.On if opt.state & QStyle.State_Selected else QIcon.Off) tab_icon_size = opt.icon.actualSize(icon_size, icon_mode, icon_state) tab_icon_size = QSize(min(tab_icon_size.width(), icon_size.width()), min(tab_icon_size.height(), icon_size.height())) icon_rect = QRect(text_rect.left(), text_rect.center().y() - tab_icon_size.height() / 2, tab_icon_size.width(), tab_icon_size.height()) icon_rect = self._style.visualRect(opt.direction, opt.rect, icon_rect) qtutils.ensure_valid(icon_rect) return icon_rect
def paintEvent(self, e): painter = QPainter(self) draw_rect = e.rect() # SLIDER--------------------------------------------------------------------- # BAR -------- painter.setPen(self._bgColor.lighter(200)) painter.drawRect(draw_rect.adjusted(0, 0, -1, -1)) painter.fillRect(draw_rect.adjusted(1, 1, -1, -1), self._bgColor) # THUMB -------- painter.setPen(self._thumbColor.lighter()) painter.drawRect(self._thumbRect.adjusted(0, 0, -1, -1)) painter.fillRect(self._thumbRect.adjusted(1, 1, -1, -1), self._thumbColor) # VALUE LABEL -------- value_text = str(self._value) value_label_size = QSize(self._fontMetrics.width(value_text), self._fontMetrics.height()) value_indicator_rect = QRect(self._thumbRect.right() + 2, self._thumbRect.top(), value_label_size.width() + 10, self._thumbRect.height()) if value_indicator_rect.right() > draw_rect.right(): value_indicator_rect.setRect( self._thumbRect.left() - value_indicator_rect.width() - 1, value_indicator_rect.top(), value_indicator_rect.width(), value_indicator_rect.height()) painter.setPen(self._indicatorColor.lighter()) painter.drawRect(value_indicator_rect.adjusted(0, 0, -1, -1)) painter.fillRect(value_indicator_rect.adjusted(1, 1, -1, -1), self._indicatorColor) painter.setPen(Qt.white) painter.drawText( value_indicator_rect.left() + value_indicator_rect.width() / 2 - value_label_size.width() / 2, value_indicator_rect.top() + value_indicator_rect.height() / 2 + value_label_size.height() / 3, value_text)
def setFixedSize_my(self, a0: QtCore.QSize) -> None: if self.label.pos().y() < 42 or a0.width() < 350: if a0.width() < self.size().width() or a0.height() < self.height(): return self.setFixedSize(a0) f = self.label.font() f.setPointSize((a0.height() - self.tableWidget.height() - 10) / 4) self.label.setFont(f) self.label_2.setFont(f)
class NorthArrow(QgsMapCanvasItem): def __init__(self, proj, canvas): super(NorthArrow, self).__init__(canvas) self.proj = proj self.canvas = canvas self.map_pos = QgsPointXY(0.0, 0.0) self.svg = QSvgRenderer(":/resources/arrow.svg") self.size = QSize(42, 64) self.corner = 1 def paint(self, painter, xxx, xxx2): """Paint north arrow on painter""" if self.svg.isValid(): pos = self.set_position(self.corner, painter.device().width(), painter.device().height()) rotation = QgsBearingUtils.bearingTrueNorth( self.canvas.mapSettings().destinationCrs(), self.canvas.mapSettings().transformContext(), self.canvas.extent().center()) rotation += self.canvas.rotation() painter.save() painter.rotate(-rotation) # To translate correctly painter.translate(pos.x(), pos.y()) painter.rotate( rotation ) # To rotate north arrow along with canvas, always pointing north # do the drawing, and draw a smooth north arrow even when rotated rectangle = QRectF(-self.size.width() / 2, -self.size.height() / 2, self.size.width(), self.size.height()) self.svg.render(painter, rectangle) painter.restore() def set_position(self, corner, width, height): """ Returns the position of the specified corner with a concrete width and height :param corner: can be 1, 2, 3 or 4. top left, top right, bot left and bot right respectively :param width: width of the paint space :param height: height of the paint space :return: QgsPointXY of the specified corner """ if corner == 1: # top left corner return QgsPointXY(0 + self.size.height() / 2, 0 + self.size.height() / 2) elif corner == 2: # top right corner return QgsPointXY(width - self.size.height() / 2, 0 + self.size.height() / 2) elif corner == 3: # bottom left corner return QgsPointXY(0 + self.size.height() / 2, height - self.size.height() / 2) elif corner == 4: # bottom right corner return QgsPointXY(width - self.size.height() / 2, height - self.size.height() / 2)
def from_WindowPos(cls, pos: WindowPos, camera: "schmereo.Camera", size: QtCore.QSize) -> "CanvasPos": scale = 2.0 / camera.zoom / size.width() # yes, width x = pos.x - size.width() / 2.0 x *= scale x += camera.center.x y = pos.y - size.height() / 2.0 y *= scale y += camera.center.y return CanvasPos(x=x, y=y)
def resizeEvent(self, _event=None): """Resize handler to update dimensions of displayed image/animation""" rect = self.geometry() movie = self.label.movie() if movie: # Manually implement aspect-preserving scaling for QMovie # # Thanks to Spencer @ https://stackoverflow.com/a/50166220/435253 # for figuring out that this approach must be taken to get smooth # up-scaling out of QMovie. width = rect.height() * self.movie_aspect if width <= rect.width(): size = QSize(width, rect.height()) else: height = rect.width() / self.movie_aspect size = QSize(rect.width(), height) movie.setScaledSize(size) elif self.orig_pixmap and not self.orig_pixmap.isNull(): # To avoid having to change which widgets are hidden and shown, # do our upscaling manually. # # This probably won't be suitable for widgets intended to be # resized as part of normal operation (aside from initially, when # the window appears) but it works well enough for my use cases and # was the quickest, simplest thing to implement. # # If your problem is downscaling very large images, I'd start by # making this one- or two-line change to see if it's good enough: # 1. Use Qt.FastTransformation to scale to the closest power of # two (eg. 1/2, 1/4, 1/8, etc.) that's still bigger and gives a # decent looking intermediate result. # 2. Use Qt.SmoothTransform to take the final step to the desired # size. # # If it's not or you need actual animation, you'll want to look up # how to do aspect-preserving display of images and animations # under QML (embeddable in a QWidget GUI using QQuickWidget) so Qt # can offload the scaling to the GPU. size = QSize(rect.width(), rect.height()) # Don't waste CPU generating a new pixmap if the resize didn't # alter the dimension that's currently bounding its size pixmap_size = self.label.pixmap().size() if (pixmap_size.width() == size.width() and pixmap_size.height() <= size.height()): return if (pixmap_size.height() == size.height() and pixmap_size.width() <= size.width()): return self.label.setPixmap(self.orig_pixmap.scaled(size, Qt.KeepAspectRatio, Qt.SmoothTransformation))
def calculate_custom_decoration_size(self, item_size: QSize, option: QStyleOptionViewItem, decoration_size: QSize): w, h = item_size.width(), item_size.height() decoration_w_or_ratio, decoration_h_or_ratio = decoration_size.width( ), decoration_size.height() if option.decorationPosition == QStyleOptionViewItem.Left: w = self.calculate_size(item_size.width(), decoration_w_or_ratio) h = self.calculate_size(item_size.height(), decoration_h_or_ratio) elif option.decorationPosition == QStyleOptionViewItem.Top: w = self.calculate_size(item_size.width(), decoration_w_or_ratio) h = self.calculate_size(item_size.height(), decoration_h_or_ratio) return QSize(w, h)
def setup_window(self, size: QSize): """Set up window dimensions, placement, title, and layout""" width = int(size.width() / 2) height = int(3 * size.height() / 5) x = size.width() / 2 - int(width / 2) y = size.height() / 2 - int(height / 2) self.setGeometry(x, y, width, height) self.setFixedSize(width, height) self.setWindowTitle("Personal Planner") self.setWindowIcon(QIcon("assets/logo.png")) self.layout.setSpacing(0) self.layout.setContentsMargins(0, 0, 0, 0) self.setLayout(self.layout)
class BoxDiagramItem(DiagramItem): def __init__(self): super().__init__() self.size = QSize(50, 50) def get_my_rect(self): parent_cx = 0 parent_cy = 0 if self.parent is not None: parent_cx = self.parent.center.x() parent_cy = self.parent.center.y() cx = self.center.x() + parent_cx cy = self.center.y() + parent_cy sw = self.size.width() sh = self.size.height() rect = QRect(cx - sw / 2, cy - sh / 2, sw, sh) return rect def point_hit_check(self, x, y): return self.get_my_rect().contains(x, y) def draw(self, qp: QPainter): rect = self.get_my_rect() brush = QBrush() brush.setStyle(Qt.SolidPattern) brush.setColor(QColor("red" if self.selected else "gray")) pen = QPen(QColor("blue" if self.hover else "black")) pen.setWidth(3 if self.hover else 1) qp.setPen(pen) qp.fillRect(rect, brush) qp.drawRect(rect)
def printImage(self): """ Print image. """ # create printer object and print output defined by the platform # the program is being run on. # QPrinter.NativeFormat is the default printer = QPrinter() printer.setOutputFormat(QPrinter.NativeFormat) # Create printer dialog to configure printer print_dialog = QPrintDialog(printer) # if the dialog is accepted by the user, begin printing if (print_dialog.exec_() == QPrintDialog.Accepted): # use QPainter to output a PDF file painter = QPainter() # begin painting device painter.begin(printer) # Set QRect to hold painter's current viewport, which # is the image_label rect = QRect(painter.viewport()) # get the size of image_label and use it to set the size # of the viewport size = QSize(self.image_label.pixmap().size()) size.scale(rect.size(), Qt.KeepAspectRatio) painter.setViewport(rect.x(), rect.y(), size.width(), size.height()) painter.setWindow(self.image_label.pixmap().rect()) # scale the image_label to fit the rect source (0, 0) painter.drawPixmap(0, 0, self.image_label.pixmap()) # end painting painter.end()
def image_large_enough(self, size: QSize) -> bool: """Check if image is equal or bigger than thumbnail size.""" return ( size.width() >= self.thumbnailSizeNeeded.width() or size.height() >= self.thumbnailSizeNeeded.height() )
def __init__(self, size: QSize): super().__init__() self._overlay_text = None # Get the default font and guess at the best size for it self._font = QPainter().font() self._font.setPixelSize(min(size.height(), size.width()) / 2)
def minimumTabSizeHint(self, index, ellipsis: bool = True): """Set the minimum tab size to indicator/icon/... text. Args: index: The index of the tab to get a size hint for. ellipsis: Whether to use ellipsis to calculate width instead of the tab's text. Return: A QSize of the smallest tab size we can make. """ text = '\u2026' if ellipsis else self.tabText(index) # Don't ever shorten if text is shorter than the ellipsis text_width = min(self.fontMetrics().width(text), self.fontMetrics().width(self.tabText(index))) icon = self.tabIcon(index) padding = config.val.tabs.padding indicator_padding = config.val.tabs.indicator_padding padding_h = padding.left + padding.right padding_h += indicator_padding.left + indicator_padding.right padding_v = padding.top + padding.bottom if icon.isNull(): icon_size = QSize(0, 0) else: extent = self.style().pixelMetric(QStyle.PM_TabBarIconSize, None, self) icon_size = icon.actualSize(QSize(extent, extent)) height = self.fontMetrics().height() + padding_v width = (text_width + icon_size.width() + padding_h + config.val.tabs.width.indicator) return QSize(width, height)
def loadRecentDocuments(self): self.recentDocuments = [] recentDocumentsPaths = self.kritaInstance.recentDocuments() for path in recentDocumentsPaths: if path: thumbnail = None extension = Path(path).suffix page = None if extension == '.kra': page = zipfile.ZipFile(path, "r") thumbnail = QImage.fromData(page.read("mergedimage.png")) if thumbnail.isNull(): thumbnail = QImage.fromData(page.read("preview.png")) else: thumbnail = QImage(path) if thumbnail.isNull(): continue thumbSize = QSize(200 * self.devicePixelRatioF, 150 * self.devicePixelRatioF) if thumbnail.width() <= thumbSize.width() or thumbnail.height( ) <= thumbSize.height(): thumbnail = thumbnail.scaled(thumbSize, Qt.KeepAspectRatio, Qt.FastTransformation) else: thumbnail = thumbnail.scaled(thumbSize, Qt.KeepAspectRatio, Qt.SmoothTransformation) thumbnail.setDevicePixelRatio(self.devicePixelRatioF) self.recentDocuments.append(thumbnail) self.modelReset.emit()
def minimumTabSizeHint(self, index): """Set the minimum tab size to indicator/icon/... text. Args: index: The index of the tab to get a size hint for. Return: A QSize. """ icon = self.tabIcon(index) padding = config.get('tabs', 'padding') padding_h = padding.left + padding.right padding_v = padding.top + padding.bottom if icon.isNull(): icon_size = QSize(0, 0) else: extent = self.style().pixelMetric(QStyle.PM_TabBarIconSize, None, self) icon_size = icon.actualSize(QSize(extent, extent)) padding_h += self.style().pixelMetric( PixelMetrics.icon_padding, None, self) indicator_width = config.get('tabs', 'indicator-width') height = self.fontMetrics().height() + padding_v width = (self.fontMetrics().width('\u2026') + icon_size.width() + padding_h + indicator_width) return QSize(width, height)
def minimumTabSizeHint(self, index): """Set the minimum tab size to indicator/icon/... text. Args: index: The index of the tab to get a size hint for. Return: A QSize. """ icon = self.tabIcon(index) padding_count = 2 if icon.isNull(): icon_size = QSize(0, 0) else: extent = self.style().pixelMetric(QStyle.PM_TabBarIconSize, None, self) icon_size = icon.actualSize(QSize(extent, extent)) padding_count += 1 indicator_width = config.get('tabs', 'indicator-width') if indicator_width != 0: indicator_width += config.get('tabs', 'indicator-space') padding_width = self.style().pixelMetric(PM_TabBarPadding, None, self) height = self.fontMetrics().height() width = (self.fontMetrics().width('\u2026') + icon_size.width() + padding_count * padding_width + indicator_width) return QSize(width, height)
def calculate_relative_position(parent_rect: QtCore.QRect, own_size: QtCore.QSize, constraint: RelativeLayoutConstraint): """ Calculates the position of the element, given its size, the position and size of the parent and a relative layout constraint. The position is the position of the parent plus the weighted size of the parent, the weighted size of the element and an offset. The weights and the offset are given by the constraint for each direction. :param parent_rect: parent coordinates and size as rectangle :param own_size: size of the element (width and height) :param constraint: relative layout constraint to apply :return: tuple of recommended x and y positions of the element """ """ Returns the left, upper corner of an object if the parent rectangle (QRect) is given and our own size (QSize) and a relative layout constraint (see RelativeLayoutConstraint). """ x = (parent_rect.x() + constraint.x[0] * parent_rect.width() + constraint.x[1] * own_size.width() + constraint.x[2]) y = (parent_rect.y() + constraint.y[0] * parent_rect.height() + constraint.y[1] * own_size.height() + constraint.y[2]) return x, y
class PictureScaleAndMove(): def __init__(self, windowSize: QSize, pictureConfig: PicturesConfig): pictureSizeInPercent = pictureConfig.getInPercent( PicturesConfig.PICTURE_SIZE_PERCENT) if pictureSizeInPercent == None: self.size = windowSize self.move = QPoint(0, 0) else: self.size = QSize(windowSize.width() * pictureSizeInPercent, windowSize.height() * pictureSizeInPercent) moveX = pictureConfig.getInPercent( PicturesConfig.PICTURE_MOVE_X_PERCENT) if moveX == None: moveX = 0 moveY = pictureConfig.getInPercent( PicturesConfig.PICTURE_MOVE_Y_PERCENT) if moveY == None: moveY = 0 pointX = int((-self.size.width() / 2) + moveX * (1 - pictureSizeInPercent) * windowSize.width()) pointY = int((-self.size.height() / 2) + moveY * (1 - pictureSizeInPercent) * windowSize.height()) self.move = QPoint(pointX, pointY) def getSize(self): return self.size def getMove(self): return self.move
def get_favicon(self): """ Get favicon for the site. This is called when the site_url can’t be loaded or when that page doesn’t contain a link tag with rel set to icon (the new way of doing site icons.) """ if self.site_icon: return if not with_pyqt: self.site_icon = None return ico_url = urllib.parse.urljoin(self.icon_url, "/favicon.ico") ico_request = urllib.request.Request(ico_url) if self.user_agent: ico_request.add_header('User-agent', self.user_agent) ico_response = urllib.request.urlopen(ico_request) if 200 != ico_response.code: self.site_icon = None return self.site_icon = QImage.fromData(ico_response.read()) max_size = QSize(self.max_icon_size, self.max_icon_size) ico_size = self.site_icon.size() if ico_size.width() > max_size.width() \ or ico_size.height() > max_size.height(): self.site_icon = self.site_icon.scaled( max_size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
def maxSize(self): size = QSize() for variation in self.d.variations: size.setWidth(max(size.width(), variation.map.width())) size.setHeight(max(size.height(), variation.map.height())) return size
class IconItemDelegate(QStyledItemDelegate): def __init__(self, parent): super().__init__(parent) self.size = QSize(50, 50) def paint(self, painter, option, index): data = index.data() if data: pixmap = QPixmap(":/icons/" + data) pixmap = pixmap.scaled(self.size.width(), self.size.height(), Qt.KeepAspectRatio) x, y = option.rect.x(), option.rect.y() w, h = pixmap.width(), pixmap.height() if w < option.rect.width(): x = x + (option.rect.width() - w) // 2 else: y = y + (option.rect.height() - h) // 2 rect = QRect(x, y, w, h) painter.drawPixmap(rect, pixmap) else: super().paint(painter, option, index) def sizeHint(self, option, index): return self.size
def minimumTabSizeHint(self, index): """Override minimumTabSizeHint because we want no hard minimum. There are two problems with having a hard minimum tab size: - When expanding is True, the window will expand without stopping on some window managers. - We don't want the main window to get bigger with many tabs. If nothing else helps, we *do* want the tabs to get smaller instead of enforcing a minimum window size. Args: index: The index of the tab to get a sizehint for. Return: A QSize. """ icon = self.tabIcon(index) padding_count = 0 if not icon.isNull(): extent = self.style().pixelMetric(QStyle.PM_TabBarIconSize, None, self) icon_size = icon.actualSize(QSize(extent, extent)) padding_count += 1 else: icon_size = QSize(0, 0) padding_width = self.style().pixelMetric(PM_TabBarPadding, None, self) height = self.fontMetrics().height() width = (self.fontMetrics().size(0, '\u2026').width() + icon_size.width() + padding_count * padding_width) return QSize(width, height)
def get_favicon(self): u""" Get favicon for the site. This is called when the site_url can’t be loaded or when that page doesn’t contain a link tag with rel set to icon (the new way of doing site icons.) """ if self.site_icon: return if not with_pyqt: self.site_icon = None return ico_url = urllib.parse.urljoin(self.icon_url, "/favicon.ico") ico_request = urllib.request.Request(ico_url) if self.user_agent: ico_request.add_header('User-agent', self.user_agent) ico_response = urllib.request.urlopen(ico_request) if 200 != ico_response.code: self.site_icon = None return self.site_icon = QImage.fromData(ico_response.read()) max_size = QSize(self.max_icon_size, self.max_icon_size) ico_size = self.site_icon.size() if ico_size.width() > max_size.width() \ or ico_size.height() > max_size.height(): self.site_icon = self.site_icon.scaled( max_size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
def resize_image_viewer(self, new_size: QSize): width = max(50, min(new_size.width(), self.MAX_SIZE.width())) height = max(50, min(new_size.height(), self.MAX_SIZE.height())) new_size = QSize(width, height) self.dg_thread.request_sync() self.resize(new_size)
def _get_crop(resolution: QSize, scan_size: int) -> QRect: """ Returns a QRect that is scan_size x scan_size in the middle of the resolution """ scan_pos_x = (resolution.width() - scan_size) // 2 scan_pos_y = (resolution.height() - scan_size) // 2 return QRect(scan_pos_x, scan_pos_y, scan_size, scan_size)
def renderToTexture(self, levelOfDetail = 1.0): # Determine the fbo size we will need. size = (self.sceneRect().size() * levelOfDetail).toSize() fboSize = nextPowerOfTwo(size) if fboSize.isEmpty(): fboSize = QSize(16, 16) # Create or re-create the fbo. if self.fbo is None or self.fbo.size() != fboSize: #del self.fbo self.fbo = QGLFramebufferObject(fboSize, self.format) if not self.fbo.isValid(): #del self.fbo self.fbo = None return 0 self.dirty = True # Return the previous texture contents if the scene hasn't changed. if self.fbo is not None and not self.dirty: return self.fbo.texture() # Render the scene into the fbo, scaling the QPainter's view # transform up to the power-of-two fbo size. painter = QPainter(self.fbo) painter.setWindow(0, 0, size.width(), size.height()) painter.setViewport(0, 0, fboSize.width(), fboSize.height()) self.render(painter) painter.end() self.dirty = False return self.fbo.texture()
def set_viewport(self, size, raise_if_empty=False): """ Set viewport size. If size is "full" viewport size is detected automatically. If can also be "<width>x<height>". .. note:: This will update all JS geometry variables, but window resize event is delivered asynchronously and so ``window.resize`` will not be invoked until control is yielded to the event loop. """ if size == 'full': size = self.web_page.mainFrame().contentsSize() self.logger.log("Contents size: %s" % size, min_level=2) if size.isEmpty(): if raise_if_empty: raise RuntimeError("Cannot detect viewport size") else: size = defaults.VIEWPORT_SIZE self.logger.log("Viewport is empty, falling back to: %s" % size) if not isinstance(size, QSize): validate_size_str(size) w, h = map(int, size.split('x')) size = QSize(w, h) self.web_page.setViewportSize(size) self._force_relayout() w, h = int(size.width()), int(size.height()) self.logger.log("viewport size is set to %sx%s" % (w, h), min_level=2) return w, h
def captureFrame(settings: QSettings, source: str, frametime: str, thumbsize: QSize = None, external: bool = False) -> QPixmap: if thumbsize is None: thumbsize = VideoService.config.thumbnails['INDEX'] capres = QPixmap() img = QTemporaryFile(os.path.join(QDir.tempPath(), 'XXXXXX.jpg')) if img.open(): imagecap = img.fileName() cmd = VideoService.findBackends(settings).ffmpeg tsize = '{0:d}x{1:d}'.format(thumbsize.width(), thumbsize.height()) args = '-hide_banner -ss {frametime} -i "{source}" -vframes 1 -s {tsize} -y "{imagecap}"'.format( **locals()) proc = VideoService.initProc() if proc.state() == QProcess.NotRunning: proc.start(cmd, shlex.split(args)) proc.waitForFinished(-1) if proc.exitStatus() == QProcess.NormalExit and proc.exitCode( ) == 0: capres = QPixmap(imagecap, 'JPG') if external: painter = QPainter(capres) painter.drawPixmap(0, 0, QPixmap(':/images/external.png', 'PNG')) painter.end() img.remove() return capres
def calculateSize(self, sizeType): totalSize = QSize() for wrapper in self.list: position = wrapper.position itemSize = QSize() if sizeType == self.MinimumSize: itemSize = wrapper.item.minimumSize() else: # sizeType == self.SizeHint itemSize = wrapper.item.sizeHint() if position in (self.North, self.South, self.Center): totalSize.setHeight(totalSize.height() + itemSize.height()) if position in (self.West, self.East, self.Center): totalSize.setWidth(totalSize.width() + itemSize.width()) return totalSize
def sizeHint(self): hint = QLabel.sizeHint(self) if self.maximum_size_hint != None: hint = QSize(max(hint.width(), self.maximum_size_hint.width()), max(hint.height(), self.maximum_size_hint.height())) self.maximum_size_hint = hint return hint
class FeatureTableWidgetHHeader(QTableWidgetItem): sub_trans = str.maketrans('0123456789', '₀₁₂₃₄₅₆₇₈₉') def __init__(self, column, sigma=None, window_size=3.5): QTableWidgetItem.__init__(self) # init # ------------------------------------------------ self.column = column self.sigma = sigma self.window_size = window_size self.pixmapSize = QSize(61, 61) self.setNameAndBrush(self.sigma) @property def brushSize(self): if self.sigma is None: return 0 else: return int(3.0 * self.sigma + 0.5) + 1 def setNameAndBrush(self, sigma, color=Qt.black): self.sigma = sigma self.setText(f'σ{self.column}'.translate(self.sub_trans)) if self.sigma is not None: total_window = (1 + 2 * int(self.sigma * self.window_size + 0.5)) self.setToolTip(f'sigma = {sigma:.1f} pixels, window diameter = {total_window:.1f}') font = QFont() font.setPointSize(10) # font.setBold(True) self.setFont(font) self.setForeground(color) pixmap = QPixmap(self.pixmapSize) pixmap.fill(Qt.transparent) painter = QPainter() painter.begin(pixmap) painter.setRenderHint(QPainter.Antialiasing, True) painter.setPen(color) brush = QBrush(color) painter.setBrush(brush) painter.drawEllipse(QRect(old_div(self.pixmapSize.width(), 2) - old_div(self.brushSize, 2), old_div(self.pixmapSize.height(), 2) - old_div(self.brushSize, 2), self.brushSize, self.brushSize)) painter.end() self.setIcon(QIcon(pixmap)) self.setTextAlignment(Qt.AlignVCenter) def setIconAndTextColor(self, color): self.setNameAndBrush(self.sigma, color)
def mapSize(self): p = RenderParams(self.map()) # The map size is the same regardless of which indexes are shifted. if (p.staggerX): size = QSize(self.map().width() * p.columnWidth + p.sideOffsetX, self.map().height() * (p.tileHeight + p.sideLengthY)) if (self.map().width() > 1): size.setHeight(size.height() + p.rowHeight) return size else: size = QSize(self.map().width() * (p.tileWidth + p.sideLengthX), self.map().height() * p.rowHeight + p.sideOffsetY) if (self.map().height() > 1): size.setWidth(size.width() + p.columnWidth) return size
def calculate_size(self): """Determine size by calculating the space of the visible items""" visible_items = min(self.model().rowCount(), self.MAX_VISIBLE_ITEMS) first_visible_row = self.verticalScrollBar().value() option = self.viewOptions() size_hint = QSize() for index in range(visible_items): tmp_size = self.itemDelegate().sizeHint( option, self.model().index(index + first_visible_row, 0)) if size_hint.width() < tmp_size.width(): size_hint = tmp_size height = size_hint.height() height *= visible_items size_hint.setHeight(height) return size_hint
def maybe_get_icon(self): u""" Get icon for the site as a QImage if we haven’t already. Get the site icon, either the 'rel="icon"' or the favicon, for the web page at url or passed in as page_html and store it as a QImage. This function can be called repeatedly and loads the icon only once. """ if self.site_icon: return if not with_pyqt: self.site_icon = None return page_request = urllib.request.Request(self.icon_url) if self.user_agent: page_request.add_header('User-agent', self.user_agent) page_response = urllib.request.urlopen(page_request) if 200 != page_response.code: self.get_favicon() return page_soup = soup(page_response, 'html.parser') try: icon_url = page_soup.find( name='link', attrs={'rel': 'icon'})['href'] except (TypeError, KeyError): self.get_favicon() return # The url may be absolute or relative. if not urllib.parse.urlsplit(icon_url).netloc: icon_url = urllib.parse.urljoin( self.url, urllib.parse.quote(icon_url.encode('utf-8'))) icon_request = urllib.request.Request(icon_url) if self.user_agent: icon_request.add_header('User-agent', self.user_agent) icon_response = urllib.request.urlopen(icon_request) if 200 != icon_response.code: self.site_icon = None return self.site_icon = QImage.fromData(icon_response.read()) max_size = QSize(self.max_icon_size, self.max_icon_size) icon_size = self.site_icon.size() if icon_size.width() > max_size.width() \ or icon_size.height() > max_size.height(): self.site_icon = self.site_icon.scaled( max_size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
def __init__(self, parent): super().__init__(parent) self.setFocusPolicy(Qt.NoFocus) self.setBackgroundRole(QPalette.Window) self.setFrameShape(QFrame.NoFrame) self.setBackgroundBrush(QBrush(Qt.NoBrush)) self._scene = QGraphicsScene(self) self.setScene(self._scene) self._keys = {} self._midi_to_key = {} for octave in range(2, 7): for idx, note in enumerate(['C', 'D', 'E', 'F', 'G', 'A', 'B']): pitch_name = '%s%d' % (note, octave) key = PianoKey( parent, 140 * octave + 20 * idx, pitch_name, PianoKey.WHITE) self._keys[pitch_name] = key self._midi_to_key[music.NOTE_TO_MIDI[pitch_name]] = key self._scene.addItem(key) for idx, note in enumerate(['C#', 'D#', '', 'F#', 'G#', 'A#', '']): if not note: continue pitch_name = '%s%d' % (note, octave) key = PianoKey( parent, 140 * octave + 20 * idx + 10, pitch_name, PianoKey.BLACK) self._keys[pitch_name] = key self._midi_to_key[music.NOTE_TO_MIDI[pitch_name]] = key self._scene.addItem(key) size = self._scene.sceneRect().size() size = QSize(int(math.ceil(size.width())) + 1, int(math.ceil(size.height())) + 10) self.setMinimumSize(size) self.setMaximumSize(size)
def maybe_get_icon(self): if self.site_icon: return if not with_pyqt: self.site_icon = None return try: icon_data = self.get_data_from_url(self.full_icon_url) except: AudioDownloader.maybe_get_icon(self) else: self.site_icon = QImage.fromData(icon_data) max_size = QSize(self.max_icon_size, self.max_icon_size) ico_size = self.site_icon.size() if ico_size.width() > max_size.width() \ or ico_size.height() > max_size.height(): self.site_icon = self.site_icon.scaled( max_size, Qt.KeepAspectRatio, Qt.SmoothTransformation)
def setColor(self, color): if type(color)!=QColor: color = QColor(color) if (self.mColor == color or not color.isValid()): return self.mColor = color size = QSize(self.iconSize()) size.setWidth(size.width()-2) size.setHeight(size.height()-2) pixmap = QPixmap(size) pixmap.fill(self.mColor) painter = QPainter(pixmap) border = QColor(Qt.black) border.setAlpha(128) painter.setPen(border) painter.drawRect(0, 0, pixmap.width() - 1, pixmap.height() - 1) painter.end() self.setIcon(QIcon(pixmap)) self.colorChanged.emit(color)
class FeatureTableWidgetHHeader(QTableWidgetItem): def __init__(self, sigma, window_size, name=None): QTableWidgetItem.__init__(self) # init # ------------------------------------------------ self.sigma = sigma self.window_size = window_size self.pixmapSize = QSize(61, 61) if not name: self.setNameAndBrush(self.sigma) else: self.setText(name) @property def brushSize(self): return int(3.0*self.sigma + 0.5)*2 + 1 def setNameAndBrush(self, sigma, color=Qt.black): self.sigma = sigma self.setText(u"σ={:.1f}px".format(self.sigma)) total_window = (1 + 2 * int(self.sigma * self.window_size + 0.5) ) self.setToolTip( "sigma = {:.1f} pixels, window diameter = {:.1f}".format(self.sigma, total_window) ) font = QFont() font.setPointSize(10) font.setBold(True) self.setFont(font) self.setForeground(color) pixmap = QPixmap(self.pixmapSize) pixmap.fill(Qt.transparent) painter = QPainter() painter.begin(pixmap) painter.setRenderHint(QPainter.Antialiasing, True) painter.setPen(color) brush = QBrush(color) painter.setBrush(brush) painter.drawEllipse(QRect(old_div(self.pixmapSize.width(),2) - old_div(self.brushSize,2), old_div(self.pixmapSize.height(),2) - old_div(self.brushSize,2), self.brushSize, self.brushSize)) painter.end() self.setIcon(QIcon(pixmap)) self.setTextAlignment(Qt.AlignVCenter) def setIconAndTextColor(self, color): self.setNameAndBrush(self.sigma, color)
class ResizeMap(QUndoCommand): def __init__(self, mapDocument, size): super().__init__(QCoreApplication.translate("Undo Commands", "Resize Map")) self.mMapDocument = mapDocument self.mSize = QSize(size) def undo(self): self.swapSize() def redo(self): self.swapSize() def swapSize(self): map = self.mMapDocument.map() oldSize = QSize(map.width(), map.height()) map.setWidth(self.mSize.width()) map.setHeight(self.mSize.height()) self.mSize = oldSize self.mMapDocument.emitMapChanged()
class Window(QWidget): def __init__(self, parent=None): super(QWidget, self).__init__(parent) self.m_iconSize = QSize(64, 64) self.m_scene = QGraphicsScene() self.m_ui = Ui_Form() self.m_ui.setupUi(self) self.m_ui.easingCurvePicker.setIconSize(self.m_iconSize) self.m_ui.easingCurvePicker.setMinimumHeight(self.m_iconSize.height() + 50) self.m_ui.buttonGroup.setId(self.m_ui.lineRadio, 0) self.m_ui.buttonGroup.setId(self.m_ui.circleRadio, 1) dummy = QEasingCurve() self.m_ui.periodSpinBox.setValue(dummy.period()) self.m_ui.amplitudeSpinBox.setValue(dummy.amplitude()) self.m_ui.overshootSpinBox.setValue(dummy.overshoot()) self.m_ui.easingCurvePicker.currentRowChanged.connect(self.curveChanged) self.m_ui.buttonGroup.buttonClicked[int].connect(self.pathChanged) self.m_ui.periodSpinBox.valueChanged.connect(self.periodChanged) self.m_ui.amplitudeSpinBox.valueChanged.connect(self.amplitudeChanged) self.m_ui.overshootSpinBox.valueChanged.connect(self.overshootChanged) self.createCurveIcons() pix = QPixmap(':/images/qt-logo.png') self.m_item = PixmapItem(pix) self.m_scene.addItem(self.m_item.pixmap_item) self.m_ui.graphicsView.setScene(self.m_scene) self.m_anim = Animation(self.m_item, b'pos') self.m_anim.setEasingCurve(QEasingCurve.OutBounce) self.m_ui.easingCurvePicker.setCurrentRow(int(QEasingCurve.OutBounce)) self.startAnimation() def createCurveIcons(self): pix = QPixmap(self.m_iconSize) painter = QPainter() gradient = QLinearGradient(0, 0, 0, self.m_iconSize.height()) gradient.setColorAt(0.0, QColor(240, 240, 240)) gradient.setColorAt(1.0, QColor(224, 224, 224)) brush = QBrush(gradient) # The original C++ code uses undocumented calls to get the names of the # different curve types. We do the Python equivalant (but without # cheating). curve_types = [(n, c) for n, c in QEasingCurve.__dict__.items() if isinstance(c, QEasingCurve.Type) and c != QEasingCurve.Custom] curve_types.sort(key=lambda ct: ct[1]) painter.begin(pix) for curve_name, curve_type in curve_types: painter.fillRect(QRect(QPoint(0, 0), self.m_iconSize), brush) curve = QEasingCurve(curve_type) if curve_type == QEasingCurve.BezierSpline: curve.addCubicBezierSegment(QPointF(0.4, 0.1), QPointF(0.6, 0.9), QPointF(1.0, 1.0)) elif curve_type == QEasingCurve.TCBSpline: curve.addTCBSegment(QPointF(0.0, 0.0), 0, 0, 0) curve.addTCBSegment(QPointF(0.3, 0.4), 0.2, 1, -0.2) curve.addTCBSegment(QPointF(0.7, 0.6), -0.2, 1, 0.2) curve.addTCBSegment(QPointF(1.0, 1.0), 0, 0, 0) painter.setPen(QColor(0, 0, 255, 64)) xAxis = self.m_iconSize.height() / 1.5 yAxis = self.m_iconSize.width() / 3.0 painter.drawLine(0, xAxis, self.m_iconSize.width(), xAxis) painter.drawLine(yAxis, 0, yAxis, self.m_iconSize.height()) curveScale = self.m_iconSize.height() / 2.0; painter.setPen(Qt.NoPen) # Start point. painter.setBrush(Qt.red) start = QPoint(yAxis, xAxis - curveScale * curve.valueForProgress(0)) painter.drawRect(start.x() - 1, start.y() - 1, 3, 3) # End point. painter.setBrush(Qt.blue) end = QPoint(yAxis + curveScale, xAxis - curveScale * curve.valueForProgress(1)) painter.drawRect(end.x() - 1, end.y() - 1, 3, 3) curvePath = QPainterPath() curvePath.moveTo(QPointF(start)) t = 0.0 while t <= 1.0: to = QPointF(yAxis + curveScale * t, xAxis - curveScale * curve.valueForProgress(t)) curvePath.lineTo(to) t += 1.0 / curveScale painter.setRenderHint(QPainter.Antialiasing, True) painter.strokePath(curvePath, QColor(32, 32, 32)) painter.setRenderHint(QPainter.Antialiasing, False) item = QListWidgetItem() item.setIcon(QIcon(pix)) item.setText(curve_name) self.m_ui.easingCurvePicker.addItem(item) painter.end() def startAnimation(self): self.m_anim.setStartValue(QPointF(0, 0)) self.m_anim.setEndValue(QPointF(100, 100)) self.m_anim.setDuration(2000) self.m_anim.setLoopCount(-1) self.m_anim.start() def curveChanged(self, row): curveType = QEasingCurve.Type(row) self.m_anim.setEasingCurve(curveType) self.m_anim.setCurrentTime(0) isElastic = (curveType >= QEasingCurve.InElastic and curveType <= QEasingCurve.OutInElastic) isBounce = (curveType >= QEasingCurve.InBounce and curveType <= QEasingCurve.OutInBounce) self.m_ui.periodSpinBox.setEnabled(isElastic) self.m_ui.amplitudeSpinBox.setEnabled(isElastic or isBounce) self.m_ui.overshootSpinBox.setEnabled(curveType >= QEasingCurve.InBack and curveType <= QEasingCurve.OutInBack) def pathChanged(self, index): self.m_anim.setPathType(index) def periodChanged(self, value): curve = self.m_anim.easingCurve() curve.setPeriod(value) self.m_anim.setEasingCurve(curve) def amplitudeChanged(self, value): curve = self.m_anim.easingCurve() curve.setAmplitude(value) self.m_anim.setEasingCurve(curve) def overshootChanged(self, value): curve = self.m_anim.easingCurve() curve.setOvershoot(value) self.m_anim.setEasingCurve(curve)
class AbstractLayout(QObject): """Manages page.Page instances with a list-like api. You can iterate over the layout itself, which yields all Page instances. You can also iterate over pages(), which only yields the Page instances that are visible(). """ redraw = pyqtSignal(QRect) changed = pyqtSignal() scaleChanged = pyqtSignal(float) def __init__(self): super(AbstractLayout, self).__init__() self._pages = [] self._size = QSize() self._margin = 4 self._spacing = 8 self._scale = 1.0 self._scaleChanged = False self._dpi = (72, 72) def own(self, page): """(Internal) Makes the page have ourselves as layout.""" if page.layout(): page.layout().remove(page) page._layout = weakref.ref(self) page.computeSize() def disown(self, page): """(Internal) Removes ourselves as owner of the page.""" page._layout = lambda: None def append(self, page): self.own(page) self._pages.append(page) def insert(self, position, page): self.own(page) self._pages.insert(position, page) def extend(self, pages): for page in pages: self.append(page) def remove(self, page): self._pages.remove(page) self.disown(page) def pop(self, index=None): page = self._pages.pop(index) self.disown(page) return page def clear(self): del self[:] def count(self): return len(self._pages) def __len__(self): return len(self._pages) def __bool__(self): return True def __contains__(self, page): return page in self._pages def __getitem__(self, item): return self._pages[item] def __delitem__(self, item): if isinstance(item, slice): for page in self._pages[item]: self.disown(page) else: self.disown(self._pages[item]) del self._pages[item] def __setitem__(self, item, new): if isinstance(item, slice): old = self._pages[item] self._pages[item] = new for page in self._pages[item]: self.own(page) for page in old: self.disown(page) else: self.disown(self._pages[item]) self._pages[item] = new self.own(new) def index(self, page): """Returns the index at which the given Page can be found in our Layout.""" return self._pages.index(page) def setSize(self, size): """Sets our size. Mainly done after layout.""" self._size = size def size(self): """Returns our size as QSize().""" return self._size def width(self): """Returns our width.""" return self._size.width() def height(self): """Returns our height.""" return self._size.height() def setDPI(self, xdpi, ydpi=None): """Sets our DPI in X and Y direction. If Y isn't given, uses the X value.""" self._dpi = xdpi, ydpi or xdpi for page in self: page.computeSize() def dpi(self): """Returns our DPI as a tuple(XDPI, YDPI).""" return self._dpi def scale(self): """Returns the scale (1.0 == 100%).""" return self._scale def setScale(self, scale): """Sets the scale (1.0 == 100%) of all our Pages.""" if scale != self._scale: self._scale = scale for page in self: page.setScale(scale) self._scaleChanged = True def setPageWidth(self, width, sameScale=True): """Sets the width of all pages. If sameScale is True (default), the largest page will be scaled to the given width (minus margin). All pages will then be scaled to that scale. If sameScale is False all pages will be scaled individually to the same width. """ if sameScale and any(self.pages()): self.setScale(self.widest().scaleForWidth(width)) else: for page in self: page.setWidth(width) def setPageHeight(self, height, sameScale=True): """Sets the height of all pages. If sameScale is True (default), the largest page will be scaled to the given height (minus margin). All pages will then be scaled to that scale. If sameScale is False all pages will be scaled individually to the same height. """ if sameScale and any(self.pages()): self.setScale(self.highest().scaleForWidth(height)) else: for page in self: page.setHeight(height) def setMargin(self, margin): """Sets the margin around the pages in pixels.""" self._margin = margin def margin(self): """Returns the margin around the pages in pixels.""" return self._margin def setSpacing(self, spacing): """Sets the space between the pages in pixels.""" self._spacing = spacing def spacing(self): """Returns the space between the pages in pixels.""" return self._spacing def fit(self, size, mode): """Fits the layout in the given ViewMode.""" if mode and any(self.pages()): scales = [] if mode & FitWidth: scales.append(self.scaleFitWidth(size.width())) if mode & FitHeight: scales.append(self.scaleFitHeight(size.height())) self.setScale(min(scales)) def scaleFitHeight(self, height): """Return the scale this layout would need to fit in the height. This method is called by fit(). The default implementation returns a suitable scale for the highest Page. """ return self.highest().scaleForHeight(height - self.margin() * 2) def scaleFitWidth(self, width): """Return the scale this layout would need to fit in the width. This method is called by fit(). The default implementation returns a suitable scale for the widest Page. """ return self.widest().scaleForWidth(width - self.margin() * 2) def update(self): """Performs the layout (positions the Pages and adjusts our size).""" self.reLayout() if self._scaleChanged: self.scaleChanged.emit(self._scale) self._scaleChanged = False self.changed.emit() def reLayout(self): """This is called by update(). You must implement this method to position the Pages and adjust our size. See Layout for a possible implementation. """ pass def updatePage(self, page): """Called by the Page when an image has been generated.""" self.redraw.emit(page.rect()) def page(self, document, pageNumber): """Returns the page (visible or not) from a Poppler.Document with page number. Returns None if that page is not available. """ # Specific layouts may use faster algorithms to find the page. try: page = self[pageNumber] except IndexError: pass else: if page.document() == document: return page for page in self: if page.document() == document and page.pageNumber() == pageNumber: return page def pages(self): """Yields our pages that are visible().""" for page in self: if page.visible(): yield page def pageAt(self, point): """Returns the page that contains the given QPoint.""" # Specific layouts may use faster algorithms to find the page. for page in self.pages(): if page.rect().contains(point): return page def pagesAt(self, rect): """Yields the pages touched by the given QRect.""" # Specific layouts may use faster algorithms to find the pages. for page in self.pages(): if page.rect().intersects(rect): yield page def linkAt(self, point): """Returns (page, link) if pos points to a Poppler.Link in a Page, else (None, None).""" page = self.pageAt(point) if page: links = page.linksAt(point) if links: return page, links[0] return None, None def widest(self): """Returns the widest visible page (in its natural page size).""" pages = list(self.pages()) if pages: return max(pages, key = lambda p: p.pageSize().width()) def highest(self): """Returns the highest visible page (in its natural page size).""" pages = list(self.pages()) if pages: return max(pages, key = lambda p: p.pageSize().height()) def maxWidth(self): """Returns the width of the widest visible page.""" page = self.widest() return page.width() if page else 0 def maxHeight(self): """Returns the height of the highest visible page.""" page = self.highest() return page.height() if page else 0 def load(self, document): """Convenience method to load all the pages of the given Poppler.Document using page.Page().""" self.clear() for num in range(document.numPages()): p = page.Page(document, num) p.setScale(self._scale) self.append(p)
oppsite = { Qt.Key_Left: Qt.Key_Right, Qt.Key_Right: Qt.Key_Left, Qt.Key_Up: Qt.Key_Down, Qt.Key_Down: Qt.Key_Up } # Return current time in seconds as a int number. def now(): return int(round(time.time()*1000)) # Return a tuple of block size def bsize() return block.width()-1, block.height()-1 # return the scale of the window def scale_sz(sz) return sz.width() * block.width(), sz.height()* block.height() # return the size of snake size def scaled_pt(p): return p.x() * block.width(), p.y() * block.height() # Snake controller Game class Game(ojbect): def __init__(self): super(Snake, self).__init__()
class ResizeHelper(QWidget): offsetChanged = pyqtSignal(QPoint) offsetXChanged = pyqtSignal(int) offsetYChanged = pyqtSignal(int) offsetBoundsChanged = pyqtSignal(QRect) def __init__(self, parent = None): super().__init__(parent) self.mMouseAnchorPoint = QPoint() self.mOffset = QPoint() self.mOldSize = QSize() self.mDragging = False self.mOffsetBounds = QRect() self.mScale = 0.0 self.mNewSize = QSize() self.mOrigOffset = QPoint() self.setMinimumSize(20, 20) self.setOldSize(QSize(1, 1)) def oldSize(self): return self.mOldSize def newSize(self): return self.mNewSize def offset(self): return self.mOffset def offsetBounds(self): return self.mOffsetBounds def setOldSize(self, size): self.mOldSize = size self.recalculateMinMaxOffset() self.recalculateScale() def setNewSize(self, size): self.mNewSize = size self.recalculateMinMaxOffset() self.recalculateScale() def setOffset(self, offset): # Clamp the offset within the offset bounds newOffset = QPoint(min(self.mOffsetBounds.right(), max(self.mOffsetBounds.left(), offset.x())), min(self.mOffsetBounds.bottom(), max(self.mOffsetBounds.top(), offset.y()))) if (self.mOffset != newOffset): xChanged = self.mOffset.x() != newOffset.x() yChanged = self.mOffset.y() != newOffset.y() self.mOffset = newOffset if (xChanged): self.offsetXChanged.emit(self.mOffset.x()) if (yChanged): self.offsetYChanged.emit(self.mOffset.y()) self.offsetChanged.emit(self.mOffset) self.update() ## Method to set only the X offset, provided for convenience. */ def setOffsetX(self, x): self.setOffset(QPoint(x, self.mOffset.y())) ## Method to set only the Y offset, provided for convenience. */ def setOffsetY(self, y): self.setOffset(QPoint(self.mOffset.x(), y)) ## Method to set only new width, provided for convenience. */ def setNewWidth(self, width): self.mNewSize.setWidth(width) self.recalculateMinMaxOffset() self.recalculateScale() ## Method to set only new height, provided for convenience. */ def setNewHeight(self, height): self.mNewSize.setHeight(height) self.recalculateMinMaxOffset() self.recalculateScale() def paintEvent(self, event): _size = self.size() - QSize(2, 2) if (_size.isEmpty()): return origX = (_size.width() - self.mNewSize.width() * self.mScale) / 2 + 0.5 origY = (_size.height() - self.mNewSize.height() * self.mScale) / 2 + 0.5 oldRect = QRect(self.mOffset, self.mOldSize) painter = QPainter(self) painter.translate(origX, origY) painter.scale(self.mScale, self.mScale) pen = QPen(Qt.black) pen.setCosmetic(True) painter.setPen(pen) painter.drawRect(QRect(QPoint(0, 0), self.mNewSize)) pen.setColor(Qt.white) painter.setPen(pen) painter.setBrush(Qt.white) painter.setOpacity(0.5) painter.drawRect(oldRect) pen.setColor(Qt.black) pen.setStyle(Qt.DashLine) painter.setOpacity(1.0) painter.setBrush(Qt.NoBrush) painter.setPen(pen) painter.drawRect(oldRect) painter.end() def mousePressEvent(self, event): self.mMouseAnchorPoint = event.pos() self.mOrigOffset = self.mOffset self.mDragging = event.button() == Qt.LeftButton def mouseMoveEvent(self, event): if (not self.mDragging): return pos = event.pos() if (pos != self.mMouseAnchorPoint): self.setOffset(self.mOrigOffset + (pos - self.mMouseAnchorPoint) / self.mScale) self.offsetChanged.emit(self.mOffset) def resizeEvent(self, event): self.recalculateScale() def recalculateScale(self): _size = self.size() - QSize(2, 2) if (_size.isEmpty()): return if self.mOldSize.width() < self.mNewSize.width(): width = self.mNewSize.width() else: width = 2 * self.mOldSize.width() - self.mNewSize.width() if self.mOldSize.height() < self.mNewSize.height(): height = self.mNewSize.height() else: height = 2 * self.mOldSize.height() - self.mNewSize.height() # Pick the smallest scale scaleW = _size.width() / width scaleH = _size.height() / height if scaleW < scaleH: self.mScale = scaleW else: self.mScale = scaleH self.update() def recalculateMinMaxOffset(self): offsetBounds = self.mOffsetBounds if (self.mOldSize.width() <= self.mNewSize.width()): offsetBounds.setLeft(0) offsetBounds.setRight(self.mNewSize.width() - self.mOldSize.width()) else: offsetBounds.setLeft(self.mNewSize.width() - self.mOldSize.width()) offsetBounds.setRight(0) if (self.mOldSize.height() <= self.mNewSize.height()): offsetBounds.setTop(0) offsetBounds.setBottom(self.mNewSize.height() - self.mOldSize.height()) else: offsetBounds.setTop(self.mNewSize.height() - self.mOldSize.height()) offsetBounds.setBottom(0) if (self.mOffsetBounds != offsetBounds): self.mOffsetBounds = offsetBounds self.offsetBoundsChanged.emit(self.mOffsetBounds)
class SquircleRenderer(QObject): # QOpenGLFunctions """docstring for SquircleRenderer""" def __init__(self, parent=None): super(SquircleRenderer, self).__init__(parent) self.m_t = 0.0 self.m_program = None self.m_viewportSize = QSize() def setT(self, t): self.m_t = t def setViewportSize(self, size): self.m_viewportSize = size def setWin(self, win): self.win = win ver = QOpenGLVersionProfile() ver.setVersion(2, 1) self.m_context = self.win.openglContext() self.gl = self.m_context.versionFunctions(ver) @pyqtSlot() def paint(self): if not self.m_program: self.gl.initializeOpenGLFunctions() self.m_program = QOpenGLShaderProgram(self) self.m_program.addShaderFromSourceCode( QOpenGLShader.Vertex, "attribute highp vec4 vertices;" "varying highp vec2 coords;" "void main() {" " gl_Position = vertices;" " coords = vertices.xy;" "}", ) self.m_program.addShaderFromSourceCode( QOpenGLShader.Fragment, "uniform lowp float t;" "varying highp vec2 coords;" "void main() {" " lowp float i = 1. - (pow(abs(coords.x), 4.) + pow(abs(coords.y), 4.));" " i = smoothstep(t - 0.8, t + 0.8, i);" " i = floor(i * 20.) / 20.;" " gl_FragColor = vec4(coords * .5 + .5, i, i);" "}", ) self.m_program.bindAttributeLocation("vertices", 0) self.m_program.link() self.m_program.bind() self.m_program.enableAttributeArray(0) values = [(-1, -1), (1, -1), (-1, 1), (1, 1)] self.m_program.setAttributeArray(0, values) self.m_program.setUniformValue("t", self.m_t) # print("DATA:",self.m_viewportSize.width(), self.m_viewportSize.height(), self.m_t)#, self.gl.glViewport) self.gl.glViewport(0, 0, self.m_viewportSize.width(), self.m_viewportSize.height()) self.gl.glDisable(self.gl.GL_DEPTH_TEST) self.gl.glClearColor(0, 0, 0, 1) self.gl.glClear(self.gl.GL_COLOR_BUFFER_BIT) self.gl.glEnable(self.gl.GL_BLEND) self.gl.glBlendFunc(self.gl.GL_SRC_ALPHA, self.gl.GL_ONE) self.gl.glDrawArrays(self.gl.GL_TRIANGLE_STRIP, 0, 4) self.m_program.disableAttributeArray(0) self.m_program.release()
class TextButton(DemoItem): BUTTON_WIDTH = 180 BUTTON_HEIGHT = 19 LEFT, RIGHT = range(2) SIDEBAR, PANEL, UP, DOWN = range(4) ON, OFF, HIGHLIGHT, DISABLED = range(4) def __init__(self, text, align=LEFT, userCode=0, parent=None, type=SIDEBAR): super(TextButton, self).__init__(parent) # Prevent a circular import. from menumanager import MenuManager self._menu_manager = MenuManager.instance() self.menuString = text self.buttonLabel = text self.alignment = align self.buttonType = type self.userCode = userCode self.scanAnim = None self.bgOn = None self.bgOff = None self.bgHighlight = None self.bgDisabled = None self.state = TextButton.OFF self.setAcceptHoverEvents(True) self.setCursor(Qt.PointingHandCursor) # Calculate the button size. if type in (TextButton.SIDEBAR, TextButton.PANEL): self.logicalSize = QSize(TextButton.BUTTON_WIDTH, TextButton.BUTTON_HEIGHT) else: self.logicalSize = QSize(int((TextButton.BUTTON_WIDTH / 2.0) - 5), int(TextButton.BUTTON_HEIGHT * 1.5)) self._prepared = False def setMenuString(self, menu): self.menuString = menu def prepare(self): if not self._prepared: self.setupHoverText() self.setupScanItem() self.setupButtonBg() self._prepared = True def boundingRect(self): return QRectF(0, 0, self.logicalSize.width(), self.logicalSize.height()) def setupHoverText(self): if not self.buttonLabel: return textItem = DemoTextItem(self.buttonLabel, Colors.buttonFont(), Colors.buttonText, -1, self) textItem.setZValue(self.zValue() + 2) textItem.setPos(16, 0) def setupScanItem(self): if Colors.useButtonBalls: scanItem = ScanItem(self) scanItem.setZValue(self.zValue() + 1) self.scanAnim = DemoItemAnimation(scanItem) x = 1.0 y = 1.5 stop = TextButton.BUTTON_WIDTH - scanItem.boundingRect().width() - x if self.alignment == TextButton.LEFT: self.scanAnim.setDuration(2500) self.scanAnim.setKeyValueAt(0.0, QPointF(x, y)) self.scanAnim.setKeyValueAt(0.5, QPointF(x, y)) self.scanAnim.setKeyValueAt(0.7, QPointF(stop, y)) self.scanAnim.setKeyValueAt(1.0, QPointF(x, y)) scanItem.setPos(QPointF(x, y)) else: self.scanAnim.setKeyValueAt(0.0, QPointF(stop, y)) self.scanAnim.setKeyValueAt(0.5, QPointF(x, y)) self.scanAnim.setKeyValueAt(1.0, QPointF(stop, y)) scanItem.setPos(QPointF(stop, y)) def setState(self, state): self.state = state self.bgOn.setRecursiveVisible(state == TextButton.ON) self.bgOff.setRecursiveVisible(state == TextButton.OFF) self.bgHighlight.setRecursiveVisible(state == TextButton.HIGHLIGHT) self.bgDisabled.setRecursiveVisible(state == TextButton.DISABLED) if state == TextButton.DISABLED: self.setCursor(Qt.ArrowCursor) else: self.setCursor(Qt.PointingHandCursor) def setupButtonBg(self): self.bgOn = ButtonBackground(self.buttonType, True, True, self.logicalSize, self) self.bgOff = ButtonBackground(self.buttonType, False, False, self.logicalSize, self) self.bgHighlight = ButtonBackground(self.buttonType, True, False, self.logicalSize, self) self.bgDisabled = ButtonBackground(self.buttonType, True, True, self.logicalSize, self) self.setState(TextButton.OFF) def hoverEnterEvent(self, event): if not self.isEnabled() or self.state == TextButton.DISABLED: return if self.state == TextButton.OFF: self.setState(TextButton.HIGHLIGHT) if Colors.noAnimations and Colors.useButtonBalls: # Wait a bit in the beginning to enhance the effect. We have # to do this here so that the adaption can be dynamic. self.scanAnim.setDuration(1000) self.scanAnim.setKeyValueAt(0.2, self.scanAnim.posAt(0)) if (self._menu_manager.window.fpsMedian > 10 or Colors.noAdapt or Colors.noTimerUpdate): if Colors.useButtonBalls: self.scanAnim.play(True, True) def hoverLeaveEvent(self, event): if self.state == TextButton.DISABLED: return self.setState(TextButton.OFF) if Colors.noAnimations and Colors.useButtonBalls: self.scanAnim.stop() def mousePressEvent(self, event): if self.state == TextButton.DISABLED: return if self.state == TextButton.HIGHLIGHT or self.state == TextButton.OFF: self.setState(TextButton.ON) def mouseReleaseEvent(self, event): if self.state == TextButton.ON: self.setState(TextButton.OFF) if self.isEnabled() and self.boundingRect().contains(event.pos()): self._menu_manager.itemSelected(self.userCode, self.menuString) def animationStarted(self, _): if self.state == TextButton.DISABLED: return self.setState(TextButton.OFF)
class Settings(object): l = logging.getLogger('Settings') def __init__(self, fileName = 'notepad.ini'): self.fileName = fileName self.notepads = [] self.mainWindowSize = QSize(1200, 700) self.mainWindowPos = QPoint(240, 200) self.browserPath = [] def load(self): self.l.debug('Loading local settings ...') config = configparser.ConfigParser() config.read(self.fileName) # load dropbox configuration self.dropboxToken = '' if config.has_section('dropbox'): self.dropboxToken = config['dropbox'].get('dropboxToken') # load browser state if config.has_section('browser'): browserSettings = config['browser'] path = browserSettings.get('path') self.browserPath = ast.literal_eval(path) # load main window position and size if config.has_section('mainWindow'): windowSettings = config['mainWindow'] # read position pos = windowSettings.get('pos', '{},{}'.format(self.mainWindowPos.x(), self.mainWindowPos.y())).split(',') self.mainWindowPos = QPoint(int(pos[0]), int(pos[1])) # read size size = windowSettings.get('size', '{},{}'.format(self.mainWindowSize.width(), self.mainWindowSize.height())).split(',') self.mainWindowSize = QSize(int(size[0]), int(size[1])) # load notepads self.notepads = [] for s in config.sections(): if s.startswith('notepad_'): npDef = None npType = config.get(s, 'type') if npType == 'local': npDef = {'name' : config.get(s, 'name'), 'type' : npType, 'path' : config.get(s, 'path') } elif npType == 'dropbox': npDef = {'name' : config.get(s, 'name'), 'type' : npType } if npDef is not None: self.notepads.append(npDef) def dump(self, channel): self.l.debug('Saving local settings ...') config = configparser.ConfigParser() config.add_section('dropbox') config.set('dropbox', 'dropboxToken', self.dropboxToken) config.add_section('browser') config.set('browser', 'path', str(self.browserPath)) config.add_section('mainWindow') config.set('mainWindow', 'pos', '{},{}'.format(self.mainWindowPos.x(), self.mainWindowPos.y())) config.set('mainWindow', 'size', '{},{}'.format(self.mainWindowSize.width(), self.mainWindowSize.height())) idx = 0 for s in self.notepads: sectName = "notepad_{}".format(idx) idx += 1 config.add_section(sectName) config.set(sectName, 'name', s['name']) config.set(sectName, 'type', s['type']) if s['type'] == 'local': config.set(sectName, 'path', s['path']) config.write(channel) def save(self): with open(self.fileName, 'w') as configfile: self.dump(configfile) def getNotepads(self): return self.notepads def addNotepad(self, npDef): self.notepads.append(npDef) def setMainWindowPos(self, pos): self.mainWindowPos = pos def setBrowserPath(self, path): self.browserPath = path def setMainWindowSize(self, size): self.mainWindowSize = size def getMainWindowPos(self): return self.mainWindowPos def getMainWindowSize(self): return self.mainWindowSize def getBrowserPath(self): return self.browserPath def getDropboxToken(self): return self.dropboxToken def setDropboxToken(self, token): self.dropboxToken = token
def paintEvent(self, event, *args): """ Custom paint event """ self.mutex.lock() # Paint custom frame image on QWidget painter = QPainter(self) painter.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.TextAntialiasing, True) # Fill background black painter.fillRect(event.rect(), self.palette().window()) if self.current_image: # DRAW FRAME # Calculate new frame image size, maintaining aspect ratio pixSize = self.current_image.size() pixSize.scale(event.rect().size(), Qt.KeepAspectRatio) # Scale image scaledPix = self.current_image.scaled(pixSize, Qt.KeepAspectRatio, Qt.SmoothTransformation) # Calculate center of QWidget and Draw image center = self.centeredViewport(self.width(), self.height()) painter.drawImage(center, scaledPix) if self.transforming_clip: # Draw transform handles on top of video preview # Get framerate fps = get_app().project.get(["fps"]) fps_float = float(fps["num"]) / float(fps["den"]) # Determine frame # of clip start_of_clip = round(float(self.transforming_clip.data["start"]) * fps_float) position_of_clip = (float(self.transforming_clip.data["position"]) * fps_float) + 1 playhead_position = float(get_app().window.preview_thread.current_frame) clip_frame_number = round(playhead_position - position_of_clip) + start_of_clip + 1 # Get properties of clip at current frame raw_properties = json.loads(self.transforming_clip_object.PropertiesJSON(clip_frame_number)) # Get size of current video player player_width = self.rect().width() player_height = self.rect().height() # Determine original size of clip's reader source_width = self.transforming_clip.data['reader']['width'] source_height = self.transforming_clip.data['reader']['height'] source_size = QSize(source_width, source_height) # Determine scale of clip scale = self.transforming_clip.data['scale'] if scale == openshot.SCALE_FIT: source_size.scale(player_width, player_height, Qt.KeepAspectRatio) elif scale == openshot.SCALE_STRETCH: source_size.scale(player_width, player_height, Qt.IgnoreAspectRatio) elif scale == openshot.SCALE_CROP: width_size = QSize(player_width, round(player_width / (float(source_width) / float(source_height)))) height_size = QSize(round(player_height / (float(source_height) / float(source_width))), player_height) if width_size.width() >= player_width and width_size.height() >= player_height: source_size.scale(width_size.width(), width_size.height(), Qt.KeepAspectRatio) else: source_size.scale(height_size.width(), height_size.height(), Qt.KeepAspectRatio) # Get new source width / height (after scaling mode applied) source_width = source_size.width() source_height = source_size.height() # Init X/Y x = 0.0 y = 0.0 # Get scaled source image size (scale_x, scale_y) sx = max(float(raw_properties.get('scale_x').get('value')), 0.001) sy = max(float(raw_properties.get('scale_y').get('value')), 0.001) scaled_source_width = source_width * sx scaled_source_height = source_height * sy # Determine gravity of clip gravity = self.transforming_clip.data['gravity'] if gravity == openshot.GRAVITY_TOP_LEFT: x += self.centeredViewport(self.width(), self.height()).x() # nudge right y += self.centeredViewport(self.width(), self.height()).y() # nudge down elif gravity == openshot.GRAVITY_TOP: x = (player_width - scaled_source_width) / 2.0 # center y += self.centeredViewport(self.width(), self.height()).y() # nudge down elif gravity == openshot.GRAVITY_TOP_RIGHT: x = player_width - scaled_source_width # right x -= self.centeredViewport(self.width(), self.height()).x() # nudge left y += self.centeredViewport(self.width(), self.height()).y() # nudge down elif gravity == openshot.GRAVITY_LEFT: y = (player_height - scaled_source_height) / 2.0 # center x += self.centeredViewport(self.width(), self.height()).x() # nudge right elif gravity == openshot.GRAVITY_CENTER: x = (player_width - scaled_source_width) / 2.0 # center y = (player_height - scaled_source_height) / 2.0 # center elif gravity == openshot.GRAVITY_RIGHT: x = player_width - scaled_source_width # right y = (player_height - scaled_source_height) / 2.0 # center x -= self.centeredViewport(self.width(), self.height()).x() # nudge left elif gravity == openshot.GRAVITY_BOTTOM_LEFT: y = (player_height - scaled_source_height) # bottom x += self.centeredViewport(self.width(), self.height()).x() # nudge right y -= self.centeredViewport(self.width(), self.height()).y() # nudge up elif gravity == openshot.GRAVITY_BOTTOM: x = (player_width - scaled_source_width) / 2.0 # center y = (player_height - scaled_source_height) # bottom y -= self.centeredViewport(self.width(), self.height()).y() # nudge up elif gravity == openshot.GRAVITY_BOTTOM_RIGHT: x = player_width - scaled_source_width # right y = (player_height - scaled_source_height) # bottom x -= self.centeredViewport(self.width(), self.height()).x() # nudge left y -= self.centeredViewport(self.width(), self.height()).y() # nudge up # Track gravity starting coordinate self.gravity_point = QPointF(x, y) # Scale to fit in widget final_size = QSize(source_width, source_height) # Adjust x,y for location x_offset = raw_properties.get('location_x').get('value') y_offset = raw_properties.get('location_y').get('value') x += (scaledPix.width() * x_offset) y += (scaledPix.height() * y_offset) self.transform = QTransform() # Apply translate/move if x or y: self.transform.translate(x, y) # Apply scale if sx or sy: self.transform.scale(sx, sy) # Apply shear shear_x = raw_properties.get('shear_x').get('value') shear_y = raw_properties.get('shear_y').get('value') if shear_x or shear_y: self.transform.shear(shear_x, shear_y) # Apply rotation rotation = raw_properties.get('rotation').get('value') if rotation: origin_x = x - self.centeredViewport(self.width(), self.height()).x() + (scaled_source_width / 2.0) origin_y = y - self.centeredViewport(self.width(), self.height()).y() + (scaled_source_height / 2.0) self.transform.translate(origin_x, origin_y) self.transform.rotate(rotation) self.transform.translate(-origin_x, -origin_y) # Apply transform painter.setTransform(self.transform) # Draw transform corners and center origin circle # Corner size cs = 6.0 os = 12.0 # Calculate 4 corners coordinates self.topLeftHandle = QRectF(0.0, 0.0, cs/sx, cs/sy) self.topRightHandle = QRectF(source_width - (cs/sx), 0, cs/sx, cs/sy) self.bottomLeftHandle = QRectF(0.0, source_height - (cs/sy), cs/sx, cs/sy) self.bottomRightHandle = QRectF(source_width - (cs/sx), source_height - (cs/sy), cs/sx, cs/sy) # Draw 4 corners painter.fillRect(self.topLeftHandle, QBrush(QColor("#53a0ed"))) painter.fillRect(self.topRightHandle, QBrush(QColor("#53a0ed"))) painter.fillRect(self.bottomLeftHandle, QBrush(QColor("#53a0ed"))) painter.fillRect(self.bottomRightHandle, QBrush(QColor("#53a0ed"))) # Calculate 4 side coordinates self.topHandle = QRectF(0.0 + (source_width / 2.0) - (cs/sx/2.0), 0, cs/sx, cs/sy) self.bottomHandle = QRectF(0.0 + (source_width / 2.0) - (cs/sx/2.0), source_height - (cs/sy), cs/sx, cs/sy) self.leftHandle = QRectF(0.0, (source_height / 2.0) - (cs/sy/2.0), cs/sx, cs/sy) self.rightHandle = QRectF(source_width - (cs/sx), (source_height / 2.0) - (cs/sy/2.0), cs/sx, cs/sy) # Draw 4 sides (centered) painter.fillRect(self.topHandle, QBrush(QColor("#53a0ed"))) painter.fillRect(self.bottomHandle, QBrush(QColor("#53a0ed"))) painter.fillRect(self.leftHandle, QBrush(QColor("#53a0ed"))) painter.fillRect(self.rightHandle, QBrush(QColor("#53a0ed"))) # Calculate center coordinate self.centerHandle = QRectF((source_width / 2.0) - (os/sx), (source_height / 2.0) - (os/sy), os/sx*2.0, os/sy*2.0) # Draw origin painter.setBrush(QColor(83, 160, 237, 122)) painter.setPen(Qt.NoPen) painter.drawEllipse(self.centerHandle) # Draw translucent rectangle self.clipRect = QRectF(0, 0, final_size.width(), final_size.height()) # Remove transform painter.resetTransform() # End painter painter.end() self.mutex.unlock()
class Settings(object): l = logging.getLogger('Settings') def __init__(self, fileName = 'shadow.ini'): self.fileName = fileName self.tzIdx = 0 self.mainWindowSize = QSize(1200, 700) self.mainWindowPos = QPoint(240, 200) def load(self): self.l.debug('Loading local settings from {}'.format(self.fileName)) config = configparser.ConfigParser() config.read(self.fileName) if config.has_section('common'): commonSettings = config['common'] self.tzIdx = int(commonSettings.get('tz', 0)) # load main window position and size if config.has_section('mainWindow'): windowSettings = config['mainWindow'] # read position pos = windowSettings.get('pos', '{},{}'.format(self.mainWindowPos.x(), self.mainWindowPos.y())).split(',') self.mainWindowPos = QPoint(int(pos[0]), int(pos[1])) # read size size = windowSettings.get('size', '{},{}'.format(self.mainWindowSize.width(), self.mainWindowSize.height())).split(',') self.mainWindowSize = QSize(int(size[0]), int(size[1])) def dump(self, channel): self.l.debug('Saving local settings ...') config = configparser.ConfigParser() config.add_section('common') config.set('common', 'tz', str(self.tzIdx)) config.add_section('mainWindow') config.set('mainWindow', 'pos', '{},{}'.format(self.mainWindowPos.x(), self.mainWindowPos.y())) config.set('mainWindow', 'size', '{},{}'.format(self.mainWindowSize.width(), self.mainWindowSize.height())) config.write(channel) def save(self): with open(self.fileName, 'w') as configfile: self.dump(configfile) def setMainWindowPos(self, pos): self.mainWindowPos = pos def setMainWindowSize(self, size): self.mainWindowSize = size def getMainWindowPos(self): return self.mainWindowPos def getMainWindowSize(self): return self.mainWindowSize def getTzIndex(self): return self.tzIdx def setTzIdx(self, idx): self.tzIdx = idx