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 __init__(self, containers: QFrame, page_containers_grid_layout: QGridLayout, gui_concentrate_handler): super(ToolDialogFrame, self).__init__() self.containers = containers self.gui_concentrate_handler = gui_concentrate_handler self.page_containers_grid_layout: QGridLayout = page_containers_grid_layout self.frame_tools = QFrame(self.containers) self.frame_tools.resize(68, 78) self.frame_tools.setStyleSheet(ToolDialogFrameStyles.all_frame_style) self.frame_tools.setFrameShape(QFrame.StyledPanel) self.frame_tools.setFrameShadow(QFrame.Raised) self.frame_tools.setObjectName("frame_tools") self.frame_concat_to_frame_tools = QFrame(self.containers) self.frame_concat_to_frame_tools.resize(500, 168) self.frame_concat_to_frame_tools.setStyleSheet( ToolDialogFrameStyles.all_frame_style) self.frame_concat_to_frame_tools.setFrameShape(QFrame.StyledPanel) self.frame_concat_to_frame_tools.setFrameShadow(QFrame.Raised) self.frame_concat_to_frame_tools.setObjectName( "frame_concat_to_frame_tools") self.ease_out = QEasingCurve(QEasingCurve.OutQuad) self.ease_in = QEasingCurve(QEasingCurve.InQuad)
def slideInWidget(self, widget, direction=Automatic): if self.indexOf(widget) == -1 or widget is self.currentWidget(): return if self._active: return self._active = True prev_widget = self.currentWidget() next_widget = widget if direction == self.Automatic: if self.indexOf(prev_widget) < self.indexOf(next_widget): direction = self.BottomToTop if self.verticalMode else self.RightToLeft else: direction = self.TopToBottom if self.verticalMode else self.LeftToRight width = self.frameRect().width() height = self.frameRect().height() # the following is important, to ensure that the new widget has correct geometry information when sliding in the first time next_widget.setGeometry(0, 0, width, height) if direction in (self.TopToBottom, self.BottomToTop): offset = QPoint( 0, height if direction == self.TopToBottom else -height) elif direction in (self.LeftToRight, self.RightToLeft): offset = QPoint(width if direction == self.LeftToRight else -width, 0) # re-position the next widget outside of the display area prev_widget_position = prev_widget.pos() next_widget_position = next_widget.pos() next_widget.move(next_widget_position - offset) next_widget.show() next_widget.raise_() prev_widget_animation = QPropertyAnimation(prev_widget, "pos") prev_widget_animation.setDuration(self.animationDuration) prev_widget_animation.setEasingCurve( QEasingCurve(self.animationEasingCurve)) prev_widget_animation.setStartValue(prev_widget_position) prev_widget_animation.setEndValue(prev_widget_position + offset) next_widget_animation = QPropertyAnimation(next_widget, "pos") next_widget_animation.setDuration(self.animationDuration) next_widget_animation.setEasingCurve( QEasingCurve(self.animationEasingCurve)) next_widget_animation.setStartValue(next_widget_position - offset) next_widget_animation.setEndValue(next_widget_position) self._animation_group.clear() self._animation_group.addAnimation(prev_widget_animation) self._animation_group.addAnimation(next_widget_animation) self._animation_group.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 setAnimation(self, animation=35): """ Set the transition animation with the given animation. animation: the number represents predefined QEasingCurves List of predefined QEasingCurves can be found from: http://doc.qt.nokia.com/4/qeasingcurve.html#Type-enum Default is QEasingCurve::InOutBack (35) """ self.__animation = animation self.__timeline.setEasingCurve(QEasingCurve(self.__animation))
def __init__(self, containers: QFrame): super(SettingDialogFrame, self).__init__() self.containers = containers self.frame_concat_to_frame_setting = QFrame(self.containers) self.frame_concat_to_frame_setting.resize(161, 78) self.frame_concat_to_frame_setting.setStyleSheet( SettingDialogFrameStyles.all_frame_style) self.frame_concat_to_frame_setting.setFrameShape(QFrame.StyledPanel) self.frame_concat_to_frame_setting.setFrameShadow(QFrame.Raised) self.frame_concat_to_frame_setting.setObjectName( "frame_concat_to_frame_setting") self.frame_setting = QFrame(self.containers) self.frame_setting.resize(68, 78) self.frame_setting.setStyleSheet( SettingDialogFrameStyles.all_frame_style) self.frame_setting.setObjectName("frame_setting") self.frame_setting.setFrameShape(QFrame.StyledPanel) self.frame_setting.setFrameShadow(QFrame.Raised) self.ease_out = QEasingCurve(QEasingCurve.OutQuad) self.ease_in = QEasingCurve(QEasingCurve.InQuad)
def __init__(self): super(PaintWidget, self).__init__() self.isLooping = True self.yPosition = 100 self.dotsRadius = 8 self.dotsColor = QtGui.QColor(255, 0, 15) self.dotsAmount = 3 self.dotsSpeed = 500 self.dotsSeparation = 70 # ANIMATION PARAMETERS self.customEasing = QEasingCurve() self.customEasing.setCustomType(self.customEasingFunc) self.animationSize = 500 self.dotsPosition = [] self.dotsAnimations = [] self.createPosition() self.createAnimation()
def __init__(self, image): self.isRunning = True self.image = image self.frame = QPixmap(image.rect().size() + QSize(0, 20)) self.frame.fill(Qt.transparent) QSplashScreen.__init__(self, self.frame, QtCore.Qt.WindowStaysOnTopHint) # COMPARISON BETWEEN EASING CURVES easingCurve = QEasingCurve() easingCurve.setCustomType(self.funkyEasingFunc) self.anim = LoadingDotsWidget(None, ypos=110, xsize=self.image.rect().size().width() + 10, sep=40, offsetx=0, speed=100, easingcurve=easingCurve, amount=3, loopingOn=3) self.anim.s_externalRepaint.connect(self.update) self.frameSize = self.rect().size() + QSize(0, 20)
def do_anim_frame_setting(self, obj: QFrame, start_location: QRect, end_location: QRect): """this method for do animation frame setting Arguments: obj {QFrame} -- [object must be do animation effect] start_location {QRect} -- [start location for anime] end_location {QRect} -- [end location for anime] """ self.anim = QPropertyAnimation(obj, b"geometry") self.anim.setStartValue(start_location) self.anim.setEndValue(end_location) self.anim.setDuration(200) self.curve = QEasingCurve(QEasingCurve.OutQuad) self.anim.setEasingCurve(self.ease_out) self.anim.start()
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()
class PaintWidget(QtWidgets.QWidget): def __init__(self): super(PaintWidget, self).__init__() self.isLooping = True self.yPosition = 100 self.dotsRadius = 8 self.dotsColor = QtGui.QColor(255, 0, 15) self.dotsAmount = 3 self.dotsSpeed = 500 self.dotsSeparation = 70 # ANIMATION PARAMETERS self.customEasing = QEasingCurve() self.customEasing.setCustomType(self.customEasingFunc) self.animationSize = 500 self.dotsPosition = [] self.dotsAnimations = [] self.createPosition() self.createAnimation() @staticmethod def customEasingFunc(x): return 3.3 * (x - 0.51) ** 3 + 0.2 * (x - 7.9) + 2 def startMoving(self): print(self.dotsAnimations) separationTime = (self.dotsSeparation / self.dotsSpeed) * 1000 for i, animation in enumerate(self.dotsAnimations): QtCore.QTimer.singleShot(i * separationTime, animation.start) def createPosition(self): for i in range(self.dotsAmount): self.dotsPosition.append(QtCore.QPoint(0, self.yPosition)) def createAnimation(self): duration = (self.animationSize / self.dotsSpeed)*1000 for i, _ in enumerate(self.dotsPosition): anim = QtCore.QVariantAnimation(self, startValue=0, endValue=self.animationSize, duration=duration, easingCurve=self.customEasing) wrapper = partial(self.updatePosition, i) anim.valueChanged.connect(wrapper) if self.isLooping: anim.finished.connect(anim.start) self.dotsAnimations.append(anim) @QtCore.pyqtSlot(int, QtCore.QVariant) def updatePosition(self, i, position): self.dotsPosition[i] = QtCore.QPoint(position, self.yPosition) self.update() def paintEvent(self, event): painter = QtGui.QPainter(self) painter.fillRect(self.rect(), QtCore.Qt.transparent) painter.setRenderHint(QtGui.QPainter.Antialiasing, True) painter.setPen(QtCore.Qt.NoPen) for position in self.dotsPosition: painter.setBrush( QtGui.QBrush(self.dotsColor, QtCore.Qt.SolidPattern) ) painter.drawEllipse(position, self.dotsRadius, self.dotsRadius)
def paintEvent(self, e): """ draw pixmap as a the background with a dark overlay HELP: currently, this cost much CPU """ painter = QPainter(self) painter.setPen(Qt.NoPen) painter.setRenderHint(QPainter.Antialiasing) painter.setRenderHint(QPainter.SmoothPixmapTransform) # calculate available size draw_width = self.width() draw_height = 10 # spacing defined in table container draw_height += self.bottom_panel.height() if self.table_container.meta_widget.isVisible(): draw_height += self.table_container.meta_widget.height() extra = self.table_container.current_extra if extra is not None and extra.isVisible(): draw_height += extra.height() if self.table_container.toolbar.isVisible(): draw_height += self.table_container.toolbar.height() scrolled = self.scrollarea.verticalScrollBar().value() max_scroll_height = draw_height - self.bottom_panel.height() # Do not draw the pixmap when it is not shown. if scrolled >= max_scroll_height: painter.save() painter.setBrush(self.palette().brush(QPalette.Window)) painter.drawRect(self.bottom_panel.rect()) painter.restore() return if self._pixmap is not None: self._draw_pixmap(painter, draw_width, draw_height, scrolled) self._draw_pixmap_overlay(painter, draw_width, draw_height, scrolled) curve = QEasingCurve(QEasingCurve.OutCubic) alpha_ratio = min(scrolled / max_scroll_height, 1) alpha = int(250 * curve.valueForProgress(alpha_ratio)) painter.save() color = self.palette().color(QPalette.Window) color.setAlpha(alpha) painter.setBrush(color) painter.drawRect(self.bottom_panel.rect()) painter.restore() else: # draw gradient for widgets(bottom panel + meta_widget + ...) above table self._draw_overlay(painter, draw_width, draw_height, scrolled) # if scrolled height > 30, draw background to seperate bottom_panel and body if scrolled >= 30: painter.save() painter.setBrush(self.palette().brush(QPalette.Window)) painter.drawRect(self.bottom_panel.rect()) painter.restore() return # since the body's background color is palette(base), we use # the color to draw background for remain empty area painter.save() painter.setBrush(self.palette().brush(QPalette.Base)) painter.drawRect(0, draw_height, draw_width, self.height() - draw_height) painter.restore() painter.end()