def addMovementAnimation(self, animGroup): # print(">>MoveAnim") for phIdx in self.photoIdxsToMove: item = self.photosInGrid[phIdx] anim = QPropertyAnimation(item.pixmap, "pos") anim.setDuration(self.moveDuration - item.gridCol * self.moveModifier) anim.setEasingCurve(QEasingCurve.Linear) startCoords = self.getCellTLCoords(item.gridRow, item.gridCol) endCoords = self.getCellTLCoords(item.gridRow, item.gridCol + self.columnMovementDist) anim.setStartValue(startCoords) anim.setEndValue(endCoords) animGroup.addAnimation(anim)
class MoveSymbol(QUndoCommand): ''' Undo/Redo command for moving symbols ''' def __init__(self, symbol_id, old_pos, new_pos, animate=False): super(MoveSymbol, self).__init__() self.setText('Move symbol') self.symbol = symbol_id self.old_pos = old_pos self.new_pos = new_pos if animate: self.animation = QPropertyAnimation(self.symbol, "position") self.animation.setDuration(500) self.animation.setStartValue(self.old_pos) self.animation.setEndValue(self.new_pos) self.animation.setEasingCurve(QEasingCurve.OutCirc) def undo(self): ''' Undo a symbol move ''' self.symbol.position = self.old_pos try: self.symbol.decisionParent.updateConnectionPointPosition() except AttributeError: pass def redo(self): ''' Apply a symbol move ''' try: self.animation.start() except AttributeError: self.symbol.position = self.new_pos try: self.symbol.decisionParent.updateConnectionPointPosition() except AttributeError: pass
def setupAnimes(self): self.shiftAnime1 = QPropertyAnimation() self.shiftAnime1.setTargetObject(self.ui.widget1) self.shiftAnime1.setPropertyName("geometry".encode()) self.shiftAnime1.setDuration(400) self.shiftAnime1.setStartValue(QRect(177, 29, 0, 571)) self.shiftAnime1.setEndValue(QRect(177, 29, 623, 571)) self.shiftAnime2 = QPropertyAnimation() self.shiftAnime2.setTargetObject(self.ui.widget2) self.shiftAnime2.setPropertyName("geometry".encode()) self.shiftAnime2.setDuration(400) self.shiftAnime2.setStartValue(QRect(800, 29, 0, 571)) self.shiftAnime2.setEndValue(QRect(177, 29, 623, 571)) self.shiftAnime3 = QPropertyAnimation() self.shiftAnime3.setTargetObject(self.ui.widget3) self.shiftAnime3.setPropertyName("geometry".encode()) self.shiftAnime3.setDuration(400) self.shiftAnime3.setStartValue(QRect(800, 29, 623, 571)) self.shiftAnime3.setEndValue(QRect(177, 29, 623, 571)) self.shiftAnime4 = QPropertyAnimation() self.shiftAnime4.setTargetObject(self.ui.widget4) self.shiftAnime4.setPropertyName("geometry".encode()) self.shiftAnime4.setDuration(400) self.shiftAnime4.setStartValue(QRect(800, 29, 623, 571)) self.shiftAnime4.setEndValue(QRect(177, 29, 623, 571)) self.selectedWidget = self.ui.widget1
def event(self, event): if event.type() == QEvent.Enter: self.anim = QPropertyAnimation(self, b"fader") self.anim.setDuration(150) self.anim.setEndValue(1.0) self.anim.start(QPropertyAnimation.DeleteWhenStopped) elif event.type() == QEvent.Leave: self.anim = QPropertyAnimation(self, b"fader") self.anim.setDuration(124) self.anim.setEndValue(0.0) self.anim.start(QPropertyAnimation.DeleteWhenStopped) else: return QToolButton.event(self, event) return False
def __init__(self): super().__init__() self.layout = QVBoxLayout(self) self.sub_widget = _NotifySubWidget(self) self.layout.addWidget(self.sub_widget) self.layout.setContentsMargins(0, 0, 0, 0) self._exit_shortcut = QShortcut(QKeySequence(Qt.Key_Escape), self) self._exit_shortcut.activated.connect(self.close) self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool) self.setAttribute(Qt.WA_TranslucentBackground) self.setAttribute(Qt.WA_MacAlwaysShowToolWindow) self.resize(width, height) self.move(QApplication.desktop().width() - self.width() - 20, 40) self.setLayout(self.layout) self._animation = QPropertyAnimation(self, b'windowOpacity') self._animation.setStartValue(0.8) self._animation.setKeyValueAt(0.4, 1) self._animation.setEndValue(0) self._animation.setDuration(5000) self._animation.finished.connect(self.close)
def switch(self, anim=True): var = False for neighbor in self.getNeighbors(): if neighbor.isEmpty: Xself = self.pos().x() Yself = self.pos().y() Xneigh = neighbor.pos().x() Yneigh = neighbor.pos().y() if self.perfectPos.x() == Xneigh and \ self.perfectPos.y() == Yneigh: self.hasPerfectPos = True else: self.hasPerfectPos = False if neighbor.perfectPos.x() == Xself and \ neighbor.perfectPos.y() == Yself: neighbor.hasPerfectPos = True else: neighbor.hasPerfectPos = False if anim: self.animation = QPropertyAnimation(self, "geometry") self.animation.setDuration(200) self.animation.setEndValue(QRect(Xneigh, Yneigh, self.width(), self.height())) self.animation.start() else: self.move(Xneigh, Yneigh) neighbor.move(Xself, Yself) var = True return var
def hide_anim(self): self.anim = QPropertyAnimation(self, "thickness") self.anim.setDuration(500) self.anim.setStartValue(self.get_thickness()) self.anim.setEndValue(0.0) self.anim.setEasingCurve(QEasingCurve.InBack) self.anim.start()
def fadeIn(self): self.anim = QPropertyAnimation(self.opacity_effect, 'opacity') self.anim.setDuration(800) self.anim.setStartValue(0) self.anim.setEndValue(1) self.anim.start() self.timer.stop()
def start_card_switch(self, card_to_show): self.slide_out_animation = QPropertyAnimation(self.active_card, "geometry") self.slide_out_animation.setDuration(ANIMATION_DURATION) self.slide_out_animation.setEasingCurve(QEasingCurve.OutCubic) self.slide_out_animation.setStartValue(self.visible_geometry) self.slide_out_animation.setEndValue(self.hidden_geometry) self.set_card_hidden(card_to_show) self.slide_in_animation = QPropertyAnimation(card_to_show, "geometry") self.slide_in_animation.setDuration(ANIMATION_DURATION) self.slide_in_animation.setEasingCurve(QEasingCurve.InCubic) self.slide_in_animation.setStartValue(self.hidden_geometry) self.slide_in_animation.setEndValue(self.visible_geometry) self.animation_group = QParallelAnimationGroup() self.animation_group.addAnimation(self.slide_out_animation) self.animation_group.addAnimation(self.slide_in_animation) self.animation_group.start()
def show_anim(self): self.anim = QPropertyAnimation(self, "thickness") self.anim.setDuration(2000) self.anim.setStartValue(self.get_thickness()) self.anim.setEndValue(50.0) self.anim.setEasingCurve(QEasingCurve.OutElastic) self.anim.start()
def createPositionAnimation(self, item, duration): ani = QPropertyAnimation(item, b'pos', self) ani.setDuration(duration) ani.setStartValue(item.pos()) width = self.squareWidth * 7 ani.setEndValue(QPointF(width - item.x(), width - item.y())) return ani
def __init__(self, parent): QObject.__init__(self, parent) self._toolbar = parent self.icon = None self.text = "" self.has_menu = False self.enabled = True self._fader = 0 self._animator = QPropertyAnimation(self) self._animator.setPropertyName(b"fader") self._animator.setTargetObject(self)
def __init__(self, symbol_id, old_pos, new_pos, animate=False): super(MoveSymbol, self).__init__() self.setText('Move symbol') self.symbol = symbol_id self.old_pos = old_pos self.new_pos = new_pos if animate: self.animation = QPropertyAnimation(self.symbol, "position") self.animation.setDuration(500) self.animation.setStartValue(self.old_pos) self.animation.setEndValue(self.new_pos) self.animation.setEasingCurve(QEasingCurve.OutCirc)
def animate(self, item, property_name, duration, start_value, end_value): """Summary Args: item (TYPE): Description property_name (TYPE): Description duration (TYPE): Description start_value (TYPE): Description end_value (TYPE): Description """ if item is not None: b_name = property_name.encode('ascii') anim = QPropertyAnimation(item.adapter, b_name) anim.setDuration(duration) anim.setStartValue(start_value) anim.setEndValue(end_value) anim.start() item.adapter.saveRef(property_name, anim)
def __init__(self, parent): super(ScreensharingToolbox, self).__init__(parent) with Resources.directory: self.setupUi() parent.installEventFilter(self) self.animation = QPropertyAnimation(self, 'pos') self.animation.setDuration(250) self.animation.setDirection(QPropertyAnimation.Forward) self.animation.setEasingCurve(QEasingCurve.Linear) # or OutCirc with 300ms self.retract_timer = QTimer(self) self.retract_timer.setInterval(3000) self.retract_timer.setSingleShot(True) self.retract_timer.timeout.connect(self.retract) self.resize(self.size().expandedTo(self.toolbox_layout.minimumSize()))
def addInsertionAnimation(self, animGroup): # Animation for added # print(">>>InsAnim") for ph in self.picItemsToAdd: # Set pixmap start location newPixmap = ph[0].pixmap row = ph[1] col = ph[2] xFact = ph[0].xFactor endCoords = self.getCellTLCoords(row, col) startCoords = QPointF(endCoords.x()-self.cellSize.width()*xFact, endCoords.y()) newPixmap.pixmap_item.setPos(startCoords) newPixmap.pixmap_item.setVisible(True) # Animate in anim = QPropertyAnimation(newPixmap, "pos") anim.setDuration(self.insertDuration) anim.setStartValue(startCoords) anim.setEasingCurve(QEasingCurve.Linear) anim.setEndValue(endCoords) animGroup.addAnimation(anim)
def animate(self, item: QGraphicsItem, property_name: str, duration: int, start_value, end_value): """ Args: item: Description property_name: Description duration: Description start_value (QVariant): Description end_value (QVariant): Description """ b_name = property_name.encode('ascii') anim = item.adapter.getRef(property_name) if anim is None: anim = QPropertyAnimation(item.adapter, b_name) item.adapter.saveRef(property_name, anim) anim.setDuration(duration) anim.setStartValue(start_value) anim.setEndValue(end_value) anim.start()
class ChannelListItem(QWidget): """ This class is responsible for managing the item in the list of channels. The list item supports a fade-in effect, which can be enabled with the should_fade parameter in the constructor. """ def __init__(self, parent, channel, fade_delay=0, should_fade=False): super(QWidget, self).__init__(parent) uic.loadUi('qt_resources/channel_list_item.ui', self) self.channel_name.setText(channel["name"]) self.channel_description_label.setText("Active 6 days ago • %d items" % channel["torrents"]) self.channel_num_subs_label.setText(str(channel["votes"])) if channel["sub"]: self.channel_subscribe_button.setText("✓ subscribed") else: self.channel_subscribe_button.setText("subscribe") if should_fade: self.opacity_effect = QGraphicsOpacityEffect(self) self.opacity_effect.setOpacity(0) self.setGraphicsEffect(self.opacity_effect) self.timer = QTimer() self.timer.setInterval(fade_delay) self.timer.timeout.connect(self.fadeIn) self.timer.start() def fadeIn(self): self.anim = QPropertyAnimation(self.opacity_effect, 'opacity') self.anim.setDuration(800) self.anim.setStartValue(0) self.anim.setEndValue(1) self.anim.start() self.timer.stop()
def __init__(self, parent): super(MiniMap, self).__init__(parent) self.setWordWrapMode(QTextOption.NoWrap) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setReadOnly(True) self.setCenterOnScroll(True) self.setMouseTracking(True) self.viewport().setCursor(Qt.PointingHandCursor) self.setTextInteractionFlags(Qt.NoTextInteraction) self._parent = parent self.highlighter = None self.lines_count = 0 if ACTIVATE_OPACITY: self.goe = QGraphicsOpacityEffect() self.setGraphicsEffect(self.goe) self.goe.setOpacity(settings.MINIMAP_MIN_OPACITY) self.animation = QPropertyAnimation(self.goe, b"opacity") self.slider = SliderArea(self) self.slider.show()
class CoffeeFundWindow(QWidget): signal_back = pyqtSignal() signal_coffee = pyqtSignal() signal_account = pyqtSignal() def __init__(self, parent=None): super().__init__() self.cards = {} # type: Dict[GuiCards, QWidget] """ Python's GC will clean up QPropertyAnimations as soon as it leaves the button handler, therefore they will appear not to work. Use members to store the animations. see http://stackoverflow.com/a/6953965 """ self.slide_in_animation = None self.slide_out_animation = None self.animation_group = None self.setObjectName("coffeeFundWindow") """ Store the position and size of visible/hidden cards for the animation sequences """ self.hidden_geometry = None self.visible_geometry = None layout = QStackedLayout() layout.setStackingMode(QStackedLayout.StackAll) card_remove = RemoveCard() self.cards[GuiCards.RemoveCard] = card_remove layout.addWidget(card_remove) card_choose_action = ChooseActionCard() self.cards[GuiCards.ChooseAction] = card_choose_action layout.addWidget(card_choose_action) card_account = AccountCard() self.cards[GuiCards.AccountInfo] = card_account layout.addWidget(card_account) # keep this as last initialized card, the last card will be shown on startup! card_start = StartCard() self.cards[GuiCards.Start] = card_start layout.addWidget(card_start) self.setLayout(layout) self.setWindowTitle("Kaffeekasse") layout.setCurrentWidget(card_start) self.active_card = None card_choose_action.button_account.clicked.connect(self.signal_account) card_choose_action.button_coffee.clicked.connect(self.signal_coffee) card_account.button_back.clicked.connect(self.signal_back) def set_card_hidden(self, card: QWidget): card.setGeometry(self.hidden_geometry) def show_start(self): self.show_card(GuiCards.Start) def show_account(self, name, value): self.cards[GuiCards.AccountInfo].set_user_name(name) self.cards[GuiCards.AccountInfo].set_balance(value) self.show_card(GuiCards.AccountInfo) def show_choose_action(self, name: str): self.cards[GuiCards.ChooseAction].set_user_name(name) self.show_card(GuiCards.ChooseAction) def show_remove(self): self.show_card(GuiCards.RemoveCard) def show_card(self, card_id: GuiCards): if self.active_card is None: self.active_card = self.cards[GuiCards.Start] if self.active_card == self.cards[card_id]: return if self.visible_geometry is None or self.hidden_geometry is None: self.visible_geometry = self.active_card.geometry() # type: QRect self.hidden_geometry = QRect(self.visible_geometry.x(), self.visible_geometry.height() * 1.5, self.visible_geometry.width(), self.visible_geometry.height()) for key in self.cards.keys(): if key != self.active_card: self.set_card_hidden(self.cards[key]) card_to_show = self.cards[card_id] self.start_card_switch(card_to_show) self.active_card = self.cards[card_id] self.layout().setCurrentWidget(self.active_card) def start_card_switch(self, card_to_show): self.slide_out_animation = QPropertyAnimation(self.active_card, "geometry") self.slide_out_animation.setDuration(ANIMATION_DURATION) self.slide_out_animation.setEasingCurve(QEasingCurve.OutCubic) self.slide_out_animation.setStartValue(self.visible_geometry) self.slide_out_animation.setEndValue(self.hidden_geometry) self.set_card_hidden(card_to_show) self.slide_in_animation = QPropertyAnimation(card_to_show, "geometry") self.slide_in_animation.setDuration(ANIMATION_DURATION) self.slide_in_animation.setEasingCurve(QEasingCurve.InCubic) self.slide_in_animation.setStartValue(self.hidden_geometry) self.slide_in_animation.setEndValue(self.visible_geometry) self.animation_group = QParallelAnimationGroup() self.animation_group.addAnimation(self.slide_out_animation) self.animation_group.addAnimation(self.slide_in_animation) self.animation_group.start()
class CircleObstruction(QColorThemedGraphicsObject): """ Useful for notifications, I...guess? """ def get_thickness(self): return self._thickness def set_thickness(self,c): self._thickness = c self.update() thickness = pyqtProperty(float, get_thickness, set_thickness) def __init__(self, sz, thickness, parent=None): super(CircleObstruction, self).__init__(parent) self._sz = sz self._thickness = thickness self._color = Qt.blue def boundingRect(self): return QRectF(-self._thickness, -self._thickness, self._sz + 2*self._thickness, self._sz + 2*self._thickness) def paint(self, painter, option, widget): # painter.setPen(QPen(self._color, # self._thickness)) painter.setBrush(self._color) painter.setPen(Qt.NoPen) painter.drawEllipse(QRectF( self._sz/2.0 - self._thickness, self._sz/2.0 - self._thickness, 2*self._thickness, 2*self._thickness, )) def show_anim(self): self.anim = QPropertyAnimation(self, "thickness") self.anim.setDuration(2000) self.anim.setStartValue(self.get_thickness()) self.anim.setEndValue(50.0) self.anim.setEasingCurve(QEasingCurve.OutElastic) self.anim.start() def hide_anim(self): self.anim = QPropertyAnimation(self, "thickness") self.anim.setDuration(500) self.anim.setStartValue(self.get_thickness()) self.anim.setEndValue(0.0) self.anim.setEasingCurve(QEasingCurve.InBack) self.anim.start()
def zoom2(self): animation = QPropertyAnimation(self, b"geometry", parent=self.parent()) animation.setDuration(200) animation.setStartValue( QRect(self.x(), self.y() + 10, self.width(), self.height())) animation.setEndValue( QRect(self.x(), self.y(), self.width(), self.height())) animation.setEasingCurve(QEasingCurve.OutBounce) animation.start()
class VCBlinkText(QWidget): def __init__(self, text: str, parent=None): super(VCBlinkText, self).__init__(parent) self.label = QLabel(text) self.label.setMinimumHeight(self.label.sizeHint().height() + 20) layout = QHBoxLayout(self) layout.addWidget(self.label) self.effect = QGraphicsOpacityEffect(self.label) self.label.setGraphicsEffect(self.effect) self.anim = QPropertyAnimation(self.effect, b'opacity') self.anim.setDuration(3500) self.anim.setLoopCount(-1) self.anim.setStartValue(1.0) self.anim.setKeyValueAt(0.5, 0.0) self.anim.setEndValue(1.0) self.anim.setEasingCurve(QEasingCurve.OutQuad) self.anim.start(QPropertyAnimation.DeleteWhenStopped) def setAlignment(self, alignment: Qt.AlignmentFlag) -> None: self.label.setAlignment(alignment) def stop(self) -> None: self.anim.stop()
class KeyBoard(Ui_ContainKeyBoard, QObject): CloseKeyBoardSignal = pyqtSignal() def __init__(self, widgetTakeInput, frameContain): QObject.__init__(self) Ui_ContainKeyBoard.__init__(self) self.setupUi(frameContain) frameContain.setGeometry(0, 0, frameContain.width(), frameContain.height()) self.frameContain = frameContain self.ShowKeyBoard() self.widgetTakeInput = widgetTakeInput self.stringEditting = self.widgetTakeInput.text() icon = QtGui.QIcon() icon.addPixmap(QtGui.QPixmap("icon/iconVietNamese.png"), QtGui.QIcon.Normal, QtGui.QIcon.On) self.pushButton_chooseLanguge.setIcon(icon) ##################for cursor alway focus to inputwidget############# self.pushButton_a.setFocusPolicy(Qt.NoFocus) self.pushButton_b.setFocusPolicy(Qt.NoFocus) self.pushButton_c.setFocusPolicy(Qt.NoFocus) self.pushButton_d.setFocusPolicy(Qt.NoFocus) self.pushButton_e.setFocusPolicy(Qt.NoFocus) self.pushButton_f.setFocusPolicy(Qt.NoFocus) self.pushButton_g.setFocusPolicy(Qt.NoFocus) self.pushButton_h.setFocusPolicy(Qt.NoFocus) self.pushButton_i.setFocusPolicy(Qt.NoFocus) self.pushButton_j.setFocusPolicy(Qt.NoFocus) self.pushButton_k.setFocusPolicy(Qt.NoFocus) self.pushButton_l.setFocusPolicy(Qt.NoFocus) self.pushButton_m.setFocusPolicy(Qt.NoFocus) self.pushButton_n.setFocusPolicy(Qt.NoFocus) self.pushButton_o.setFocusPolicy(Qt.NoFocus) self.pushButton_p.setFocusPolicy(Qt.NoFocus) self.pushButton_q.setFocusPolicy(Qt.NoFocus) self.pushButton_r.setFocusPolicy(Qt.NoFocus) self.pushButton_s.setFocusPolicy(Qt.NoFocus) self.pushButton_u.setFocusPolicy(Qt.NoFocus) self.pushButton_v.setFocusPolicy(Qt.NoFocus) self.pushButton_t.setFocusPolicy(Qt.NoFocus) self.pushButton_w.setFocusPolicy(Qt.NoFocus) self.pushButton_x.setFocusPolicy(Qt.NoFocus) self.pushButton_y.setFocusPolicy(Qt.NoFocus) self.pushButton_z.setFocusPolicy(Qt.NoFocus) self.pushButton_close.setFocusPolicy(Qt.NoFocus) self.pushButton_backSpace.setFocusPolicy(Qt.NoFocus) self.pushButton_shift.setFocusPolicy(Qt.NoFocus) self.pushButton_cap.setFocusPolicy(Qt.NoFocus) self.pushButton_space.setFocusPolicy(Qt.NoFocus) self.pushButton_enter1.setFocusPolicy(Qt.NoFocus) self.pushButton_enter1.setFocusPolicy(Qt.NoFocus) self.pushButton_chooseLanguge.setFocusPolicy(Qt.NoFocus) self.pushButton_dot.setFocusPolicy(Qt.NoFocus) self.pushButton_1.setFocusPolicy(Qt.NoFocus) self.pushButton_2.setFocusPolicy(Qt.NoFocus) self.pushButton_3.setFocusPolicy(Qt.NoFocus) self.pushButton_4.setFocusPolicy(Qt.NoFocus) self.pushButton_5.setFocusPolicy(Qt.NoFocus) self.pushButton_6.setFocusPolicy(Qt.NoFocus) self.pushButton_7.setFocusPolicy(Qt.NoFocus) self.pushButton_8.setFocusPolicy(Qt.NoFocus) self.pushButton_9.setFocusPolicy(Qt.NoFocus) self.pushButton_0.setFocusPolicy(Qt.NoFocus) self.pushButton_xo.setFocusPolicy(Qt.NoFocus) self.pushButton_acong.setFocusPolicy(Qt.NoFocus) #################################################################### self.keyboardObj = Controller() self.pushButton_a.clicked.connect( lambda: self.__ButtonAnphabetClick("a", self.pushButton_a)) self.pushButton_b.clicked.connect( lambda: self.__ButtonAnphabetClick("b", self.pushButton_b)) self.pushButton_c.clicked.connect( lambda: self.__ButtonAnphabetClick("c", self.pushButton_c)) self.pushButton_d.clicked.connect( lambda: self.__ButtonAnphabetClick("d", self.pushButton_d)) self.pushButton_e.clicked.connect( lambda: self.__ButtonAnphabetClick("e", self.pushButton_e)) self.pushButton_f.clicked.connect( lambda: self.__ButtonAnphabetClick("f", self.pushButton_f)) self.pushButton_g.clicked.connect( lambda: self.__ButtonAnphabetClick("g", self.pushButton_g)) self.pushButton_h.clicked.connect( lambda: self.__ButtonAnphabetClick("h", self.pushButton_h)) self.pushButton_i.clicked.connect( lambda: self.__ButtonAnphabetClick("i", self.pushButton_i)) self.pushButton_j.clicked.connect( lambda: self.__ButtonAnphabetClick("j", self.pushButton_j)) self.pushButton_k.clicked.connect( lambda: self.__ButtonAnphabetClick("k", self.pushButton_k)) self.pushButton_l.clicked.connect( lambda: self.__ButtonAnphabetClick("l", self.pushButton_l)) self.pushButton_m.clicked.connect( lambda: self.__ButtonAnphabetClick("m", self.pushButton_m)) self.pushButton_n.clicked.connect( lambda: self.__ButtonAnphabetClick("n", self.pushButton_n)) self.pushButton_o.clicked.connect( lambda: self.__ButtonAnphabetClick("o", self.pushButton_o)) self.pushButton_p.clicked.connect( lambda: self.__ButtonAnphabetClick("p", self.pushButton_p)) self.pushButton_q.clicked.connect( lambda: self.__ButtonAnphabetClick("q", self.pushButton_q)) self.pushButton_r.clicked.connect( lambda: self.__ButtonAnphabetClick("r", self.pushButton_r)) self.pushButton_s.clicked.connect( lambda: self.__ButtonAnphabetClick("s", self.pushButton_s)) self.pushButton_t.clicked.connect( lambda: self.__ButtonAnphabetClick("t", self.pushButton_t)) self.pushButton_u.clicked.connect( lambda: self.__ButtonAnphabetClick("u", self.pushButton_u)) self.pushButton_v.clicked.connect( lambda: self.__ButtonAnphabetClick("v", self.pushButton_v)) self.pushButton_w.clicked.connect( lambda: self.__ButtonAnphabetClick("w", self.pushButton_w)) self.pushButton_x.clicked.connect( lambda: self.__ButtonAnphabetClick("x", self.pushButton_x)) self.pushButton_y.clicked.connect( lambda: self.__ButtonAnphabetClick("y", self.pushButton_y)) self.pushButton_z.clicked.connect( lambda: self.__ButtonAnphabetClick("z", self.pushButton_z)) self.pushButton_dot.clicked.connect( lambda: self.__ButtonAnphabetClick(".", self.pushButton_dot)) self.pushButton_1.clicked.connect( lambda: self.__ButtonAnphabetClick("1", self.pushButton_1)) self.pushButton_2.clicked.connect( lambda: self.__ButtonAnphabetClick("2", self.pushButton_2)) self.pushButton_3.clicked.connect( lambda: self.__ButtonAnphabetClick("3", self.pushButton_3)) self.pushButton_4.clicked.connect( lambda: self.__ButtonAnphabetClick("4", self.pushButton_4)) self.pushButton_5.clicked.connect( lambda: self.__ButtonAnphabetClick("5", self.pushButton_5)) self.pushButton_6.clicked.connect( lambda: self.__ButtonAnphabetClick("6", self.pushButton_6)) self.pushButton_7.clicked.connect( lambda: self.__ButtonAnphabetClick("7", self.pushButton_7)) self.pushButton_8.clicked.connect( lambda: self.__ButtonAnphabetClick("8", self.pushButton_8)) self.pushButton_9.clicked.connect( lambda: self.__ButtonAnphabetClick("9", self.pushButton_9)) self.pushButton_0.clicked.connect( lambda: self.__ButtonAnphabetClick("0", self.pushButton_0)) self.pushButton_xo.clicked.connect( lambda: self.__ButtonAnphabetClick('/', self.pushButton_xo)) self.pushButton_acong.clicked.connect( lambda: self.__ButtonAnphabetClick("@", self.pushButton_acong)) self.pushButton_close.clicked.connect( lambda: self.__ButtonControlClick("close", self.pushButton_close)) self.pushButton_backSpace.clicked.connect( lambda: self.__ButtonControlClick("backspace", self. pushButton_backSpace)) self.pushButton_shift.clicked.connect( lambda: self.__ButtonControlClick("shift", self.pushButton_shift)) self.pushButton_cap.clicked.connect( lambda: self.__ButtonControlClick("caplock", self.pushButton_cap)) self.pushButton_space.clicked.connect( lambda: self.__ButtonControlClick("space", self.pushButton_space)) self.pushButton_enter1.clicked.connect( lambda: self.__ButtonControlClick("enter", self.pushButton_enter1)) self.pushButton_enter2.clicked.connect( lambda: self.__ButtonControlClick("enter", self.pushButton_enter2)) self.pushButton_chooseLanguge.clicked.connect( lambda: self.__ButtonControlClick("chooseLanguage", self. pushButton_chooseLanguge)) """ neu widget lay input bi che. Dat vi tri cua no len tren ban phim """ def SetWidgetTakeInputPosAboveKeyboard(self, widgetTakeInput): if ((self.widgetTakeInput.y() + self.widgetTakeInput.height()) > 220): self.oldPositon = self.widgetTakeInput.x() self.widgetTakeInput.setGeometry( self.widgetTakeInput.x(), (220 - self.widgetTakeInput.height() - 1), self.widgetTakeInput.width(), self.widgetTakeInput.height()) def __ButtonAnphabetClick(self, character, button): if (not self.keyboardObj._caps_lock): self.keyboardObj.press(character) self.keyboardObj.release(character) else: self.keyboardObj.press(character.upper()) self.keyboardObj.release(character.upper()) r = random.randint(0, 255) g = random.randint(0, 255) b = random.randint(0, 255) button.setStyleSheet( "margin: 1px; padding: 7px;\nbackground-color: rgb(%s, %s, %s);\ncolor: rgba(0,190,255,255);\nborder-style: solid;\nborder-radius: 3px;\nborder-width: 1px;\nborder-color: rgba(0,140,255,255);\n" % (r, g, b)) timer = QTimer(self) timer.timeout.connect(lambda: self.__ResetButtonStyle(button, timer)) timer.start(500) def __ResetButtonStyle(self, button, timer): button.setStyleSheet("margin: 1px; padding: 7px;\n" "background-color: rgb(255, 255, 255);\n" "color: rgba(0,190,255,255);\n" "border-style: solid;\n" "border-radius: 3px;\n" "border-width: 1px;\n" "border-color: rgba(0,140,255,255);\n" "") timer.stop() timer.deleteLater() def __ButtonControlClick(self, button, obj): if (button == "close"): self.CloseKeyBoard() if (button == "shift"): self.keyboardObj.press(Key.shift) self.keyboardObj.release(Key.shift) if (button == "caplock"): self.keyboardObj.press(Key.caps_lock) self.keyboardObj.release(Key.caps_lock) if (button == "space"): self.keyboardObj.press(Key.space) self.keyboardObj.release(Key.space) if (button == "enter"): self.keyboardObj.press(Key.enter) self.keyboardObj.release(Key.enter) if (button == "backspace"): self.keyboardObj.press(Key.backspace) self.keyboardObj.release(Key.backspace) if (button == "chooseLanguage"): self.keyboardObj.press(Key.ctrl) self.keyboardObj.press(Key.shift) self.keyboardObj.release(Key.ctrl) self.keyboardObj.release(Key.shift) r = random.randint(0, 255) g = random.randint(0, 255) b = random.randint(0, 255) obj.setStyleSheet( "margin: 1px; padding: 7px;\nbackground-color: rgb(%s, %s, %s);\ncolor: rgba(0,190,255,255);\nborder-style: solid;\nborder-radius: 3px;\nborder-width: 1px;\nborder-color: rgba(0,140,255,255);\n" % (r, g, b)) timer = QTimer(self) timer.timeout.connect(lambda: self.__ResetButtonStyle(obj, timer)) timer.start(500) # def __ButtonAnphabetRelease(self, character): # self.keyboardObj.release(character) # def __ButtonControlRelease(self, button): # if(button == "close"): # self.CloseKeyBoard() # if(button == "shift"): # self.keyboardObj.release(Key.shift) # if(button == "caplock"): # self.keyboardObj.release(Key.caps_lock) # if(button == "space"): # self.keyboardObj.release(Key.space) # if(button == "enter"): # self.keyboardObj.release(Key.enter) def ShowKeyBoard(self): self.frameContain.show() self.openAnim = QPropertyAnimation(self.frameContain, b"geometry") self.openAnim.setDuration(300) self.openAnim.setStartValue( QtCore.QRect(0, 480, self.frameContain.width(), self.frameContain.height())) self.openAnim.setEndValue( QtCore.QRect(0, 480 - self.frameContain.height(), self.frameContain.width(), self.frameContain.height())) self.openAnim.start() def CloseKeyBoard(self): self.CloseAnim = QPropertyAnimation(self.frameContain, b"geometry") self.CloseAnim.setDuration(300) self.CloseAnim.setEndValue( QtCore.QRect(0, 480, self.frameContain.width(), self.frameContain.height())) self.CloseAnim.setStartValue( QtCore.QRect(0, 480 - self.frameContain.height(), self.frameContain.width(), self.frameContain.height())) self.CloseAnim.start() self.CloseAnim.finished.connect( lambda: self.CloseKeyBoardSignal.emit()) # self.frameContain.deleteLater() def __ChangeWidgetTakeInput(self, widgetTakeInput): self.widgetTakeInput = widgetTakeInput
def __init__(self, scene, x_max, y_max, back_color): scene = QGraphicsScene(0, 0, x_max, y_max) scene.setBackgroundBrush(back_color) color = [Qt.green, Qt.lightGray, Qt.darkYellow, QtGui.QColor.fromRgb(255, 85, 0)] self.anim_butt = [ QGraphicsRectWidget(color[j]) for j in range(4) ] for j in range(4): scene.addItem(self.anim_butt[j]) self.window = QGraphicsView(scene) self.window.setFrameStyle(0) self.window.setAlignment(Qt.AlignLeft | Qt.AlignTop) self.window.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.window.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.machine = QStateMachine() self.group = QState() self.timer = QTimer() self.timer.setInterval(1250) self.timer.setSingleShot(True) self.group.entered.connect(self.timer.start) # set states positions anim_state_rects = [ [QRect(x_max*xp/6, y_max*yp/4, 8, 8) for xp in range(4)] for yp in range(4) ] self.states = [ self.createGeometryState( self.anim_butt[0], anim_state_rects[0][j], self.anim_butt[1], anim_state_rects[1][j], self.anim_butt[2], anim_state_rects[2][j], self.anim_butt[3], anim_state_rects[3][j], self.group ) for j in range(4) ] self.group.setInitialState(self.states[0]) self.animationGroup = QParallelAnimationGroup() self.anim = QPropertyAnimation(self.anim_butt[3], 'geometry') self.anim.setDuration(1250) self.anim.setEasingCurve(QEasingCurve.InBack) self.animationGroup.addAnimation(self.anim) self.subGroup = QSequentialAnimationGroup(self.animationGroup) self.subGroup.addPause(100) self.anim = QPropertyAnimation(self.anim_butt[2], 'geometry') self.anim.setDuration(1000) self.anim.setEasingCurve(QEasingCurve.OutElastic) self.subGroup.addAnimation(self.anim) self.subGroup = QSequentialAnimationGroup(self.animationGroup) self.subGroup.addPause(500) self.anim = QPropertyAnimation(self.anim_butt[1], 'geometry') self.anim.setDuration(500) self.anim.setEasingCurve(QEasingCurve.OutElastic) self.subGroup.addAnimation(self.anim) self.subGroup = QSequentialAnimationGroup(self.animationGroup) self.subGroup.addPause(750) self.anim = QPropertyAnimation(self.anim_butt[0], 'geometry') self.anim.setDuration(250) self.anim.setEasingCurve(QEasingCurve.OutElastic) self.subGroup.addAnimation(self.anim) self.stateSwitcher = StateSwitcher(self.machine) self.group.addTransition(self.timer.timeout, self.stateSwitcher) for j in range(4): self.stateSwitcher.addState(self.states[j], self.animationGroup) self.machine.addState(self.group) self.machine.setInitialState(self.group) self.machine.start()
class Preferences(QDialog): # Signal to warn that the window is closed settingsClosed = pyqtSignal() def __init__(self, parent=None): super(Preferences, self).__init__(parent) # Main container # This contains a grid main_box = QVBoxLayout(self) main_box.setContentsMargins(200, 50, 200, 100) # The grid contains two containers # left container and right container grid = QGridLayout() # Left Container left_container = QVBoxLayout() left_container.setContentsMargins(0, 0, 0, 0) # General group_gral = QGroupBox(self.tr("General")) box_gral = QVBoxLayout(group_gral) # Updates btn_updates = QPushButton(self.tr("Check for updates")) box_gral.addWidget(btn_updates) # Language group_language = QGroupBox(self.tr("Language")) box = QVBoxLayout(group_language) # Find .qm files in language path available_langs = file_manager.get_files_from_folder( settings.LANGUAGE_PATH) languages = ["English"] + available_langs self._combo_lang = QComboBox() box.addWidget(self._combo_lang) self._combo_lang.addItems(languages) self._combo_lang.currentIndexChanged[int].connect( self._change_lang) if PSetting.LANGUAGE: self._combo_lang.setCurrentText(PSetting.LANGUAGE) box.addWidget(QLabel(self.tr("(Requires restart)"))) # Add widgets left_container.addWidget(group_gral) left_container.addWidget(group_language) left_container.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Expanding)) # Right Container right_container = QVBoxLayout() right_container.setContentsMargins(0, 0, 0, 0) # Editor editor_group = QGroupBox(self.tr("Editor Configurations")) box_editor = QHBoxLayout(editor_group) # Current line self._highlight_current_line = QCheckBox( self.tr("Highlight Current Line")) self._highlight_current_line.setChecked( PSetting.HIGHLIGHT_CURRENT_LINE) self._highlight_current_line.stateChanged[int].connect( self.__current_line_value_changed) box_editor.addWidget(self._highlight_current_line) # Matching paren self._matching_paren = QCheckBox(self.tr("Matching Parenthesis")) self._matching_paren.setChecked( PSetting.MATCHING_PARENTHESIS) self._matching_paren.stateChanged[int].connect( self.__set_enabled_matching_parenthesis) box_editor.addWidget(self._matching_paren) # Font group font_group = QGroupBox(self.tr("Font")) font_grid = QGridLayout(font_group) font_grid.addWidget(QLabel(self.tr("Family")), 0, 0) self._combo_font = QFontComboBox() self._combo_font.setCurrentFont(PSetting.FONT) font_grid.addWidget(self._combo_font, 0, 1) font_grid.addWidget(QLabel(self.tr("Point Size")), 1, 0) self._combo_font_size = QComboBox() fdb = QFontDatabase() combo_sizes = fdb.pointSizes(PSetting.FONT.family()) current_size_index = combo_sizes.index( PSetting.FONT.pointSize()) self._combo_font_size.addItems([str(f) for f in combo_sizes]) self._combo_font_size.setCurrentIndex(current_size_index) font_grid.addWidget(self._combo_font_size, 1, 1) right_container.addWidget(editor_group) right_container.addWidget(font_group) right_container.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Expanding)) # Add widgets grid.addLayout(left_container, 0, 0) grid.addLayout(right_container, 0, 1) main_box.addLayout(grid) # Button close and reset hbox = QHBoxLayout() hbox.setSpacing(20) hbox.addItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) btn_cancel = QPushButton(self.tr("Back")) hbox.addWidget(btn_cancel) btn_reset = QPushButton(self.tr("Reset Configurations")) hbox.addWidget(btn_reset) main_box.addLayout(hbox) # Overlay self.overlay = overlay_widget.OverlayWidget(self) self.overlay.hide() # Effect and animations self.effect = QGraphicsOpacityEffect() self.setGraphicsEffect(self.effect) duration, x = 180, 150 # Animation duration # Animation start # Opacity animation self.opacity_animation_s = QPropertyAnimation(self.effect, b"opacity") self.opacity_animation_s.setDuration(duration) self.opacity_animation_s.setStartValue(0.0) self.opacity_animation_s.setEndValue(1.0) # X animation self.x_animation_s = QPropertyAnimation(self, b"geometry") self.x_animation_s.setDuration(duration) self.x_animation_s.setStartValue(QRect(x, 0, parent.width(), parent.height())) self.x_animation_s.setEndValue(QRect(0, 0, parent.width(), parent.height())) # Animation end # Opacity animation self.opacity_animation_e = QPropertyAnimation(self.effect, b"opacity") self.opacity_animation_e.setDuration(duration) self.opacity_animation_e.setStartValue(1.0) self.opacity_animation_e.setEndValue(0.0) # X animation self.x_animation_e = QPropertyAnimation(self, b"geometry") self.x_animation_e.setDuration(duration) self.x_animation_e.setStartValue(QRect(0, 0, parent.width(), parent.height())) self.x_animation_e.setEndValue(QRect(-x, 0, parent.width(), parent.height())) # Group animation start self.group_animation_s = QParallelAnimationGroup() self.group_animation_s.addAnimation(self.opacity_animation_s) self.group_animation_s.addAnimation(self.x_animation_s) # Group animation end self.group_animation_e = QParallelAnimationGroup() self.group_animation_e.addAnimation(self.opacity_animation_e) self.group_animation_e.addAnimation(self.x_animation_e) # Connections self.group_animation_e.finished.connect( self._on_group_animation_finished) btn_cancel.clicked.connect(self.close) btn_reset.clicked.connect(self._reset_settings) btn_updates.clicked.connect(self._check_for_updates) # self.thread.finished.connect(self._on_thread_finished) self._combo_font.currentFontChanged.connect( self._change_font) self._combo_font_size.currentTextChanged.connect( self._change_font_size) def __current_line_value_changed(self, value): qs = QSettings(settings.SETTINGS_PATH, QSettings.IniFormat) qs.setValue('highlight_current_line', value) PSetting.HIGHLIGHT_CURRENT_LINE = value def __set_enabled_matching_parenthesis(self, value): qs = QSettings(settings.SETTINGS_PATH, QSettings.IniFormat) qs.setValue("matching_parenthesis", value) PSetting.MATCHING_PARENTHESIS = value def _change_font(self, font): # FIXME: un quilombo esto central = Pireal.get_service("central") mcontainer = central.get_active_db() if mcontainer is not None: query_widget = mcontainer.query_container.currentWidget() if query_widget is not None: weditor = query_widget.get_editor() if weditor is not None: qs = QSettings(settings.SETTINGS_PATH, QSettings.IniFormat) weditor.set_font(font) qs.setValue("font", font) def _change_font_size(self, size): # FIXME: un quilombo esto font = self._combo_font.currentFont() font.setPointSize(int(size)) central = Pireal.get_service("central") mcontainer = central.get_active_db() if mcontainer is not None: query_widget = mcontainer.query_container.currentWidget() if query_widget is not None: weditor = query_widget.get_editor() if weditor is not None: qs = QSettings(settings.SETTINGS_PATH, QSettings.IniFormat) weditor.set_font(font) qs.setValue("font", font) def showEvent(self, event): super(Preferences, self).showEvent(event) self.group_animation_s.start() def resizeEvent(self, event): self.overlay.resize(self.size()) event.accept() def done(self, result): self.res = result self.group_animation_e.start() def _on_group_animation_finished(self): super(Preferences, self).done(self.res) self.settingsClosed.emit() def _check_for_updates(self): # Thread self._thread = QThread() self._updater = updater.Updater() self._updater.moveToThread(self._thread) self._thread.started.connect(self._updater.check_updates) self._updater.finished.connect(self.__on_thread_update_finished) # Show overlay widget self.overlay.show() # Start thread self._thread.start() def __on_thread_update_finished(self): # Hide overlay widget self.overlay.hide() self._thread.quit() msg = QMessageBox(self) if not self._updater.error: if self._updater.version: version = self._updater.version msg.setWindowTitle(self.tr("New version available!")) msg.setText(self.tr("Check the web site to " "download <b>Pireal {}</b>".format( version))) download_btn = msg.addButton(self.tr("Download!"), QMessageBox.YesRole) msg.addButton(self.tr("Cancel"), QMessageBox.RejectRole) msg.exec_() r = msg.clickedButton() if r == download_btn: webbrowser.open_new( "http://centaurialpha.github.io/pireal") else: msg.setWindowTitle(self.tr("Information")) msg.setText(self.tr("Last version installed")) msg.addButton(self.tr("Ok"), QMessageBox.AcceptRole) msg.exec_() else: msg.critical(self, self.tr("Error"), self.tr("Connection error")) self._thread.deleteLater() self._updater.deleteLater() def _reset_settings(self): """ Remove all settings """ msg = QMessageBox(self) msg.setWindowTitle(self.tr("Reset Settings")) msg.setText(self.tr("Are you sure you want to clear all settings?")) msg.setIcon(QMessageBox.Question) msg.addButton(self.tr("No"), QMessageBox.NoRole) yes_btn = msg.addButton(self.tr("Yes"), QMessageBox.YesRole) msg.exec_() r = msg.clickedButton() if r == yes_btn: QSettings(settings.SETTINGS_PATH, QSettings.IniFormat).clear() self.close() def _change_lang(self, index): lang = self._combo_lang.itemText(index) qs = QSettings(settings.SETTINGS_PATH, QSettings.IniFormat) qs.setValue('language', lang)
def linear_translation_animation(self, obj, ix, iy, x, y, duration=1000): anim = QPropertyAnimation(obj, b'pos') anim.setDuration(duration) anim.setStartValue(QPointF(ix, iy)) anim.setEndValue(QPointF(x, y)) return anim
class PopupWidget(QtWidgets.QWidget): # enum PointerPosition LeftSide = 0 RightSide = 1 TopSide = 2 BottomSide = 3 NoPointer = 4 LR_MARGIN = 10.0 #8.0 #/* left / right margin */ TB_MARGIN = 8.0 #5.5 #/* top / bottom margin */ didHide = pyqtSignal() didShow = pyqtSignal() onClick = pyqtSignal() onRightClick = pyqtSignal() def __init__(self, parent=None, timeout=None, delete_on_hide=True, activation_hides=True, dark_mode=False): ''' parent should be a window or None timeout is the amount of time, in milliseconds, to show the widget before it is auto-hidden. None is no timeout. delete_on_hide, if True, will auto-delete this widget after it is hidden due to the timeout or due to calling hide(). ''' super().__init__(parent) self.layout = QtWidgets.QGridLayout(self) if sys.platform != 'darwin': self.layout.setContentsMargins(20, 20, 20, 20) self.animation = QPropertyAnimation(self) self.final_opacity = 1.0 self.popup_opacity = 1.0 self.pointerPos = self.LeftSide self._timer = None self.activation_hides = activation_hides self.dark_mode = dark_mode and sys.platform.lower() != "darwin" #self.resize(200, 50) self.setWindowFlags(Qt.FramelessWindowHint | Qt.Tool) self.setAttribute(Qt.WA_TranslucentBackground) self.setAttribute(Qt.WA_ShowWithoutActivating) self.animation.setTargetObject(self) self.animation.setPropertyName(b'popupOpacity') self.animation.setDuration(200) self.setLayout(self.layout) if parent: parent.installEventFilter(self) self.timeout = timeout self.delete_on_hide = delete_on_hide def getPointerPosition(self): return self.pointerPos def setPointerPosition(self, r): self.pointerPos = r self.update() @pyqtProperty( float ) # Property so that Qt animations work. You may set the actual attrbute directly and ingore this in client code def popupOpacity(self): return self.popup_opacity @popupOpacity.setter def popupOpacity(self, value): self.popup_opacity = value self.setWindowOpacity(value) @pyqtProperty( float ) # Property so that Qt animations work. You may set the actual attrbute directly and ingore this in client code def finalOpacity(self): return self.final_opacity @finalOpacity.setter def finalOpacity(self, value): self.final_opacity = value def paintEvent(self, e): #// Draw the popup here #// You can always pick an image and use drawPixmap to #// draw it in order to make things simpler painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) painter.setClipRegion(e.region()) painter.fillRect(e.rect(), QColor(0, 0, 0, 0)) #// Prepare the popup dimensions roundedRectDimensions = QRectF() roundedRectDimensions.setX(self.rect().x() + self.LR_MARGIN) roundedRectDimensions.setY(self.rect().y() + self.TB_MARGIN) roundedRectDimensions.setWidth(self.rect().width() - self.LR_MARGIN * 2.0) roundedRectDimensions.setHeight(self.rect().height() - self.TB_MARGIN * 2.0) pal = QPalette(self.palette()) painter.setBrush( QBrush( pal.color( QPalette.Window if self.dark_mode else QPalette.Mid))) pen = QPen() pen.setColor( pal.color(QPalette.Light if self.dark_mode else QPalette.Button)) pen.setWidth(3) painter.setPen(pen) #// Draw the popup body painter.drawRoundedRect(roundedRectDimensions, self.LR_MARGIN * 2.0, self.TB_MARGIN * 2.0) painter.setPen(Qt.NoPen) painter.setBrush( QBrush( pal.color( QPalette.BrightText if self.dark_mode else QPalette.Dark))) #// Draw the popup pointer based on relPos self.drawPopupPointer(painter) e.accept() def drawPopupPointer(self, p): r = QRectF(self.rect()) if self.pointerPos == self.LeftSide: PPIX_X = self.LR_MARGIN PPIX_Y = PPIX_X * 2.0 points = [ QPointF(r.x() + PPIX_X, r.height() / 2.0 - PPIX_Y / 2.0), QPointF(r.x() + PPIX_X, r.height() / 2.0 + PPIX_Y / 2.0), QPointF(r.x(), r.height() / 2.0), ] p.drawPolygon(*points) if self.pointerPos == self.RightSide: PPIX_X = self.LR_MARGIN PPIX_Y = PPIX_X * 2.0 points = [ QPointF(r.right() - PPIX_X, r.height() / 2.0 - PPIX_Y / 2.0), QPointF(r.right() - PPIX_X, r.height() / 2.0 + PPIX_Y / 2.0), QPointF(r.right(), r.height() / 2.0), ] p.drawPolygon(*points) if self.pointerPos == self.TopSide: PPIX_Y = self.TB_MARGIN PPIX_X = PPIX_Y * 2.0 points = [ QPointF(r.x() + r.width() / 2.0 - PPIX_X / 2.0, r.top() + PPIX_Y), QPointF(r.x() + r.width() / 2.0 + PPIX_X / 2.0, r.top() + PPIX_Y), QPointF(r.x() + r.width() / 2.0, r.top()), ] p.drawPolygon(*points) if self.pointerPos == self.BottomSide: PPIX_Y = self.TB_MARGIN PPIX_X = PPIX_Y * 2.0 points = [ QPointF(r.x() + r.width() / 2.0 - PPIX_X / 2.0, r.bottom() - PPIX_Y), QPointF(r.x() + r.width() / 2.0 + PPIX_X / 2.0, r.bottom() - PPIX_Y), QPointF(r.x() + r.width() / 2.0, r.bottom()), ] p.drawPolygon(*points) def showRelativeTo(self, w): s = self.size() self.moveRelativeTo(w) self.hide() self.show() if self.pointerPos == self.NoPointer: self.raise_() if s != self.size(): # show caused widget resize.. recenter self.moveRelativeTo(w) def moveRelativeTo(self, w): if not w: print( "INTERNAL ERROR: PopupWidget::showRelativeTo got passed a NULL widget pointer! Ignoring.. FIXME!" ) return p = w.mapToGlobal(QPoint(0, 0)) if self.pointerPos == self.LeftSide: p.setX(p.x() + w.width()) p.setY(p.y() - self.height() // 2 + w.height() // 2) elif self.pointerPos == self.RightSide: p.setX(p.x() - self.width()) p.setY(p.y() - self.height() // 2 + w.height() // 2) elif self.pointerPos == self.BottomSide: p.setX(p.x() + w.width() // 2 - self.width() // 2) p.setY(p.y() - self.height()) elif self.pointerPos == self.TopSide: p.setX(p.x() + w.width() // 2 - self.width() // 2) p.setY(p.y() + w.height()) else: #// just center it on the widget p.setX(p.x() + w.width() // 2 - self.width() // 2) p.setY(p.y() + w.height() // 2 - self.height() // 2) if self.isVisible(): self.raise_() self.move(p) def _killTimer(self): if self._timer: self._timer.stop() self._timer.deleteLater() self._timer = None def _startTimer(self, target): self._killTimer() self._timer = QTimer(self) self._timer.setSingleShot(True) def timeout(): self._killTimer() target() self._timer.timeout.connect(timeout) self._timer.start(int(self.timeout)) def showEvent(self, e): super().showEvent(e) if not e.isAccepted(): return if self.animation.state() == QAbstractAnimation.Running: return self.setWindowOpacity(0.0) self.animation.setStartValue(0.0) self.animation.setEndValue(self.final_opacity) self.didShow.emit() self._cleanUp() self.animation.setDirection(QAbstractAnimation.Forward) self.animation.start() if isinstance(self.timeout, (float, int)) and self.timeout > 0: def autoHide(): self._cleanUp() self._startTimer(self.hideAnimated) self.animation.finished.connect(autoHide) def hideEvent(self, e): super().hideEvent(e) if e.isAccepted(): self._cleanUp() if self.delete_on_hide: self.setParent(None) self.deleteLater() def _disconnectFinished(self): try: self.animation.finished.disconnect() except: pass def hideAnimated(self): if self.animation.state() == QAbstractAnimation.Running: return self._cleanUp() self.animation.setDirection(QAbstractAnimation.Backward) self.animation.start() def doHide(): self._cleanUp() self.hide() self.didHide.emit() self.animation.finished.connect(doHide) def eventFilter(self, obj, e): evts = (QEvent.Move, QEvent.Resize, QEvent.Close, QEvent.Hide, QEvent.Show) if self.activation_hides: evts = (*evts, QEvent.WindowStateChange, QEvent.WindowDeactivate) if e.type() in evts: # if the parent window is moved or otherwise touched, make this popup go away self.hideAnimated() return False def mousePressEvent(self, e): if e.button() == Qt.LeftButton: self.onClick.emit() e.accept() elif e.button() == Qt.RightButton: self.onRightClick.emit() e.accept() def _cleanUp(self): ''' Forces animation and timer to stop. This is essential to force the object into a known consistent state ready for deletion, restart of animations, etc. ''' self._disconnectFinished() self._killTimer() self.animation.stop()
def animation(self): self.anim = QPropertyAnimation(self.frame, b"geometry") self.anim.setDuration(1000) self.anim.setStartValue(QRect(0, 0, 100, 30)) self.anim.setEndValue(QRect(250, 250, 100, 30)) self.anim.start()
class AnimatedLabel(QLabel): """Class that extends the default functionality of the QLabel adding an animation to it""" SLOW_DURATION = 1500 MID_DURATION = 1000 FAST_DURATION = 500 def __init__(self, parent=None, color='yellow'): """Constructor of the class Keyword Arguments: parent {ui.gui.views.toolbar.ToolBar} -- Parent of this widget (default: {None}) color {str} -- Color name for the label (default: {'yellow'}) """ QLabel.__init__(self, parent) self.config_animation(self.MID_DURATION) self.setPixmap(QPixmap(':/assets/recording.png')) self.setFixedSize(40, 40) self.setAlignment(Qt.AlignCenter) self.setStyleSheet('color: ' + color) self.setScaledContents(True) def config_animation(self, duration): """Start a fading animation for this label Arguments: duration {int} -- Duration in milliseconds of a complete fadein-fadeout cycle """ self.effect = QGraphicsOpacityEffect() self.setGraphicsEffect(self.effect) self.fadeout = QPropertyAnimation(self.effect, b"opacity") self.fadeout.setDuration(duration) self.fadeout.setStartValue(1) self.fadeout.setEndValue(0) self.fadein = QPropertyAnimation(self.effect, b"opacity") self.fadein.setDuration(duration) self.fadein.setStartValue(0) self.fadein.setEndValue(1) self.group_animation = QSequentialAnimationGroup() self.group_animation.addAnimation(self.fadein) self.group_animation.addAnimation(self.fadeout) self.group_animation.setLoopCount(-1) def start_animation(self): self.group_animation.start() def stop_animation(self): self.group_animation.stop()
def initAnimation(self, startPos, endPos): # 透明度动画 opacityAnimation = QPropertyAnimation(self, b"opacity") opacityAnimation.setStartValue(1.0) opacityAnimation.setEndValue(0.0) # 设置动画曲线 opacityAnimation.setEasingCurve(QEasingCurve.InQuad) opacityAnimation.setDuration(4000) # 在4秒的时间内完成 # 往上移动动画 moveAnimation = QPropertyAnimation(self, b"pos") moveAnimation.setStartValue(startPos) moveAnimation.setEndValue(endPos) moveAnimation.setEasingCurve(QEasingCurve.InQuad) moveAnimation.setDuration(5000) # 在5秒的时间内完成 # 并行动画组(目的是让上面的两个动画同时进行) self.animationGroup = QParallelAnimationGroup(self) self.animationGroup.addAnimation(opacityAnimation) self.animationGroup.addAnimation(moveAnimation) self.animationGroup.finished.connect(self.close) # 动画结束时关闭窗口 self.animationGroup.start()
class MyForm(QDialog): def __init__(self): super(MyForm, self).__init__() self.ui = uic.loadUi('Game.ui', self) self.ui.frame.setStyleSheet('background-image:url("Lane.png")') self.image = [ "Car-Blue.png", "Car-Green.png", "Car-Oranges.png", "Car-Pink.png" ] self.ui.pushButton_2.clicked.connect(self.Go) self.ui.pushButton_3.clicked.connect(self.stop) self.ui.pushButton_4.clicked.connect(self.Go) self.ui.pushButton_5.clicked.connect(self.resume) self.setWindowTitle('Car Rush') self.setWindowIcon(QIcon('Supercar.png')) self.point = 0 self.x = 190 self.y = 400 self.settime2 = 6000 self.speed2 = 6000 self.settime = 5000 self.speed = 5000 def Go(self): print("Go") MF3 = MyForm3() MF3.show() self.resetpoint() self.setPos() self.Disable() # Xe1 self.timmer = QtCore.QTimer() self.timmer.start(self.settime) self.timmer.timeout.connect(self.create) # Xe2 self.timmerx2 = QtCore.QTimer() self.timmerx2.start(self.settime2) self.timmerx2.timeout.connect(self.create2) # point self.timmer_point = QtCore.QTimer() self.timmer_point.start(self.speed) self.timmer_point.timeout.connect(self.calculatePoint) #point 2 self.timmer_point2 = QtCore.QTimer() self.timmer_point2.start(self.speed2) self.timmer_point2.timeout.connect(self.calculatePoint2) # check self.timmer2 = QtCore.QTimer() self.timmer2.start(100) self.timmer2.timeout.connect(self.check) def create(self): image = random.choice(self.image) self.labelXe1.setPixmap(QPixmap(image)) self.lstR = [30, 190, 360] self.a = random.choice(self.lstR) self.CN = QPropertyAnimation(self.ui.labelXe1, b"geometry") self.CN.setDuration(self.speed) self.CN.setStartValue(QRect(self.a, -50, 100, 150)) self.CN.setEndValue(QRect(self.a, 800, 100, 150)) self.CN.start() def create2(self): self.lstR2 = [30, 190, 360] r2 = random.choice(self.lstR2) if r2 != self.a: self.labelXe2.setPixmap(QPixmap(random.choice(self.image))) self.CN2 = QPropertyAnimation(self.ui.labelXe2, b"geometry") self.CN2.setDuration(self.speed) self.CN2.setStartValue(QRect(r2, -50, 100, 150)) self.CN2.setEndValue(QRect(r2, 800, 100, 150)) self.CN2.start() else: self.lstR2.remove(self.a) r2 = random.choice(self.lstR2) self.labelXe2.setPixmap(QPixmap(random.choice(self.image))) self.CN2 = QPropertyAnimation(self.ui.labelXe2, b"geometry") self.CN2.setDuration(self.speed) self.CN2.setStartValue(QRect(r2, -50, 100, 150)) self.CN2.setEndValue(QRect(r2, 800, 100, 150)) self.CN2.start() def Disable(self): print("Disable") self.ui.pushButton_2.setEnabled(False) self.ui.pushButton_3.setEnabled(True) self.ui.pushButton_4.setEnabled(False) self.ui.pushButton_5.setEnabled(True) def Enabled(self): print("Enabled") self.ui.pushButton_2.setEnabled(True) self.ui.pushButton_3.setEnabled(False) self.ui.pushButton_4.setEnabled(True) self.ui.pushButton_5.setEnabled(False) def setPos(self): self.ui.labelXe1.setGeometry(180, -200, 100, 150) self.ui.label_10.setGeometry(190, 400, 100, 150) self.x = 190 self.y = 400 def check(self): # tọa độ xe 1 w_car = self.ui.labelXe1.width() h_car = self.ui.labelXe1.height() X_car = self.ui.labelXe1.x() Y_car = self.ui.labelXe1.y() # tọa độ xe 2 w_car2 = self.ui.labelXe2.width() h_car2 = self.ui.labelXe2.height() X_car2 = self.ui.labelXe2.x() Y_car2 = self.ui.labelXe2.y() # chiều cao xe đỏ w_card = self.ui.label_10.width() h_card = self.ui.label_10.height() # print("Xe 1 ", X_car, Y_car, "|","Xe 2 ", X_car2, Y_car2,"|", self.x, self.y) if (self.x == X_car): self.timmer_point.stop() self.timmer_point2.stop() self.timmer2.stop() self.timmer.stop() self.CN.stop() self.timmerx2.stop() self.ui.labelXe1.move(-200, -200) self.ui.labelXe2.move(-200, -200) self.Enabled() print("Game Over") self.MF2 = MyForm2() self.MF2.ui.pushButton.clicked.connect(self.PlayAgain) self.MF2.ui.label.setText('SCORE: ' + str(self.point)) self.MF2.show() if ((self.x <= (X_car2 + w_car2) and self.x >= X_car2) or (self.x + w_card >= X_car2 and self.x + w_card <= X_car2 + w_car2)) \ and ((h_car2 + Y_car2 >= self.y) and (h_card + Y_car2 <= self.y + h_card) or ((Y_car2 >= self.y) and (Y_car2 <= self.y + w_card))): self.timmer_point.stop() self.timmer_point2.stop() self.timmer2.stop() self.timmer.stop() self.CN.stop() self.timmerx2.stop() self.CN2.stop() self.ui.labelXe1.move(-200, -200) self.ui.labelXe2.move(-200, -200) self.Enabled() print("Game Over") self.MF2 = MyForm2() self.MF2.ui.pushButton.clicked.connect(self.PlayAgain) self.MF2.ui.label.setText('SCORE: ' + str(self.point)) self.MF2.show() def PlayAgain(self): self.Go() self.MF2.close() def move(self): self.anim = QPropertyAnimation(self.ui.label_10, b"geometry") self.anim.setDuration(-10) self.anim.setStartValue(QRect(self.x, self.y, 100, 150)) self.anim.setEndValue(QRect(self.x, self.y, 100, 150)) self.anim.start() def stop(self): self.timmer.stop() self.timmerx2.stop() self.timmer2.stop() self.timmer_point.stop() self.timmer_point2.stop() self.CN.pause() self.CN2.pause() print("End") def resume(self): self.timmer.start() self.timmerx2.start() self.timmer2.start() self.timmer_point.start() self.timmer_point2.start() self.CN.resume() self.CN2.resume() def calculatePoint2(self): if self.ui.labelXe2.y() > 700: self.point += 10 print(self.point) self.ui.label.setText(str(self.point)) def calculatePoint(self): if self.ui.labelXe1.y() > 700: self.point += 10 self.ui.label.setText(str(self.point)) if self.point == 20: self.settime = self.settime - 500 self.speed = self.speed - 500 print(self.settime, self.speed) print(self.point) if self.point == 50: self.settime = self.settime - 500 self.speed = self.speed - 500 print(self.settime, self.speed) if self.point == 70: self.settime = self.settime - 500 self.speed = self.speed - 500 print(self.settime, self.speed) if self.point == 100: self.settime = self.settime - 500 self.speed = self.speed - 500 print(self.settime, self.speed) if self.point == 150: self.settime = self.settime - 500 self.speed = self.speed - 500 print(self.settime, self.speed) if self.point == 200: self.settime = self.settime - 500 self.speed = self.speed - 500 print(self.settime, self.speed) def resetpoint(self): self.point = 0 self.ui.label.setText(str(0)) def keyPressEvent(self, e): if e.key() == QtCore.Qt.Key_W or e.key() == QtCore.Qt.Key_Up: if self.y > 250: self.y -= 30 self.x += 0 elif e.key() == QtCore.Qt.Key_S or e.key() == QtCore.Qt.Key_Down: if self.y < 420: self.y += 30 # self.x += 0 elif e.key() == QtCore.Qt.Key_A or e.key() == QtCore.Qt.Key_Right: if self.x > 10: self.y += 0 self.x -= 30 elif e.key() == QtCore.Qt.Key_D or e.key() == QtCore.Qt.Key_Left: if self.x < 350: self.y += 0 self.x += 30 self.move()
def createAnimation(self, target, index): '''创建动画''' # 暂停动画一 PauseAnimation1 = QPauseAnimation(target) PauseAnimation1.setDuration(150 * index) # 并行动画组一 # #透明度动画一 OpacityAnimation1 = QPropertyAnimation(target, b"opacity") OpacityAnimation1.setDuration(400) OpacityAnimation1.setStartValue(0) OpacityAnimation1.setEndValue(1) # #移动动画一 MoveAnimation1 = _MoveAnimation(target, self.parent, self.easing) MoveAnimation1.setMoveType(_MoveAnimation.MOVE1) MoveAnimation1.setDuration(400) MoveAnimation1.setStartValue(QPoint(0, 0)) MoveAnimation1.setEndValue(QPoint(self.parent.width() / 4.0, 0)) # 添加到并行动画里面 ParallelAnimation1 = QParallelAnimationGroup() ParallelAnimation1.addAnimation(OpacityAnimation1) ParallelAnimation1.addAnimation(MoveAnimation1) # 移动动画二 MoveAnimation2 = _MoveAnimation(target, self.parent, self.easing) MoveAnimation2.setMoveType(_MoveAnimation.MOVE2) MoveAnimation2.setDuration(2000) MoveAnimation2.setEndValue(QPoint((self.parent.width() / 4.0) * 3.0, 0)) # 并行动画组二 # #透明度动画二 OpacityAnimation2 = QPropertyAnimation(target, b"opacity") OpacityAnimation2.setDuration(400) OpacityAnimation2.setStartValue(1) OpacityAnimation2.setEndValue(0) # #移动动画三 MoveAnimation3 = _MoveAnimation(target, self.parent, self.easing) MoveAnimation3.setMoveType(_MoveAnimation.MOVE3) MoveAnimation3.setDuration(400) MoveAnimation3.setEndValue(QPoint(self.parent.width(), 0)) # 添加到并行动画里面 ParallelAnimation2 = QParallelAnimationGroup() ParallelAnimation2.addAnimation(OpacityAnimation2) ParallelAnimation2.addAnimation(MoveAnimation3) # 暂停动画二 PauseAnimation2 = QPauseAnimation(target) PauseAnimation2.setDuration(150 * (5 - index - 1)) # 串行动画组 self.setLoopCount(-1) # 无限循环 self.addAnimation(PauseAnimation1) self.addAnimation(ParallelAnimation1) self.addAnimation(MoveAnimation2) self.addAnimation(ParallelAnimation2) self.addAnimation(PauseAnimation2)
def startAmination(self): self.anim = QPropertyAnimation(self.ui.labelpic, b'geometry') self.anim.setDuration(10000) self.anim.setStartValue(QRect(160, 70, 80, 80)) self.anim.setEndValue(QRect(160, 70, 320, 460)) self.anim.start()
class Attr(WizardWidget): drag_label = "Attribute <attr>" acceptable_tags = ['attr'] def __init__(self, parent=None): # This changes to true when this attribute is being viewed/edited self.active = False self.ef = 0 WizardWidget.__init__(self, parent=parent) # an in memory record of all the contents that were selected self._previous_index = -1 cbo = self.ui.comboBox self._domain_content = dict.fromkeys(range(cbo.count()), None) self.parent_ui = parent self.series = None def build_ui(self): """ Build and modify this widget's GUI Returns ------- None """ self.ui = UI_attr.Ui_attribute_widget() self.ui.setupUi(self) # self.ui.fgdc_attrdef.installEventFilter(self) self.ui.fgdc_attrdef.setMouseTracking(True) self.ui.fgdc_attrdefs.installEventFilter(self) self.ui.attrdomv_contents.installEventFilter(self) self.ui.place_holder.installEventFilter(self) self.setup_dragdrop(self) self.ui.comboBox.currentIndexChanged.connect(self.change_domain) self.ui.fgdc_attr.mousePressEvent = self.mousePressEvent self.ui.fgdc_attrlabl.mousePressEvent = self.attrlabl_press self.ui.fgdc_attrdef.mousePressEvent = self.attrdef_press self.ui.fgdc_attrdefs.mousePressEvent = self.attrdefs_press self.ui.comboBox.mousePressEvent = self.combo_press self.domain = None self.ui.comboBox.setCurrentIndex(3) def mousePressEvent(self, event): self.activate() def attrlabl_press(self, event): self.activate() return QLineEdit.mousePressEvent(self.ui.fgdc_attrlabl, event) def attrdef_press(self, event): self.activate() return QPlainTextEdit.mousePressEvent(self.ui.fgdc_attrdef, event) def attrdefs_press(self, event): self.activate() return QLineEdit.mousePressEvent(self.ui.fgdc_attrdefs, event) def combo_press(self, event): self.activate() return QComboBox.mousePressEvent(self.ui.comboBox, event) def clear_domain(self): for child in self.ui.attrdomv_contents.children(): if isinstance(child, QWidget): child.deleteLater() def set_series(self, series): """ store a series with this attri Parameters ---------- series : pandas series Returns ------- None """ self.series = series def guess_domain(self): """ return the index of the domain the associated series is thought to best match. if there are less than twenty unique items in the series the guess is enumerated if it's numeric the guess is range. else it's unrepresentable Returns ------- int : index of the domain the associated series is thought to best match """ # given a series of data take a guess as to which # domain type is appropriate if self.series is not None: uniques = self.series.unique() if len(uniques) < 20: return 0 elif np.issubdtype(self.series.dtype, np.number): return 1 else: return 3 # without a series to introspect we're going to default to udom return 3 def store_current_content(self): """ Save the current contents (xml format) into our domain contents dict Returns ------- None """ if self.domain is not None and not sip.isdeleted(self.domain): cur_xml = self.domain.to_xml() if cur_xml.tag == 'udom': self._domain_content[3] = cur_xml elif cur_xml.tag == 'codesetd': self._domain_content[2] = cur_xml elif cur_xml.tag == 'rdom': self._domain_content[1] = cur_xml elif cur_xml.tag == 'attr': self._domain_content[0] = cur_xml def populate_domain_content(self, which='guess'): """ Fill out this widget with the content from it's associated series Parameters ---------- which : str, optional, one of 'guess' or the index to force if guess introspect the series associated with this attribute and make a best guess as to which domain to use. Returns ------- None """ self.clear_domain() if which == 'guess': index = self.guess_domain() else: index = which self.ui.comboBox.setCurrentIndex(index) if index == 0: self.domain = edom_list.EdomList(parent=self) elif index == 1: self.domain = rdom.Rdom(parent=self) elif index == 2: self.domain = codesetd.Codesetd(parent=self) else: self.domain = udom.Udom(parent=self) if self._domain_content[index] is not None: # This domain has been used before, display previous content self.domain.from_xml(self._domain_content[index]) elif self.series is not None and index == 0: uniques = self.series.unique() if len(uniques) > 100: msg = "There are more than 100 unique values in this field." msg += "\n This tool cannot smoothly display that many " \ "entries. " msg += "\nTypically an enumerated domain is not used with " \ "that many unique entries." msg += "\n\nOnly the first one hundred are displayed below!" msg += "\nYou will likely want to change the domain to one " \ "of the other options." QMessageBox.warning(self, "Too many unique entries", msg) self.domain.populate_from_list(uniques[:101]) else: self.domain.populate_from_list(uniques) elif self.series is not None and index == 1: try: self.domain.ui.fgdc_rdommin.setText(str(self.series.min())) except: self.domain.ui.fgdc_rdommin.setText('') try: self.domain.ui.fgdc_rdommax.setText(str(self.series.max())) except: self.domain.ui.fgdc_rdommax.setText('') self.ui.attrdomv_contents.layout().addWidget(self.domain) def change_domain(self): """ When changing the domain we must first store the current contents in our internal contents dictionary before loading the next. Returns ------- None """ if self.active: self.store_current_content() self.clear_domain() self.populate_domain_content(self.ui.comboBox.currentIndex()) def supersize_me(self): """ Expand this attribute and display it's contents Returns ------- None """ if not self.active: self.active = True self.animation = QPropertyAnimation(self, b"minimumSize") self.animation.setDuration(200) self.animation.setEndValue(QSize(345, self.height())) self.animation.start() self.ui.attrdomv_contents.show() self.ui.place_holder.hide() cbo = self.ui.comboBox self.populate_domain_content(cbo.currentIndex()) def regularsize_me(self): """ Collapse this attribute and hide it's content Returns ------- None """ if self.active: self.store_current_content() self.animation = QPropertyAnimation(self, b"minimumSize") self.animation.setDuration(200) self.animation.setEndValue(QSize(100, self.height())) self.animation.start() self.clear_domain() self.ui.place_holder.show() self.active = False def activate(self): """ When an attribute is activated minimize all the other attributes in the parent attribute list Returns ------- None """ if self.active: #we're already big so do nothing pass else: if self.parent_ui is not None: self.parent_ui.minimize_children() self.supersize_me() def contextMenuEvent(self, event): self.in_context = True clicked_widget = self.childAt(event.pos()) menu = QMenu(self) copy_action = menu.addAction(QIcon('copy.png'), '&Copy') copy_action.setStatusTip('Copy to the Clipboard') paste_action = menu.addAction(QIcon('paste.png'), '&Paste') paste_action.setStatusTip('Paste from the Clipboard') menu.addSeparator() insert_before = menu.addAction(QIcon('paste.png'), 'Insert before') insert_before.setStatusTip('insert an empty attribute (column) ' 'before this one') insert_after = menu.addAction(QIcon('paste.png'), 'Insert After') insert_after.setStatusTip('insert an empty attribute (column) after' ' this one') delete_action = menu.addAction(QIcon('delete.png'), '&Delete') delete_action.setStatusTip('Delete this atttribute (column)') if hasattr(clicked_widget, 'help_text') and clicked_widget.help_text: menu.addSeparator() help_action = menu.addAction("Help") else: help_action = None menu.addSeparator() clear_action = menu.addAction("Clear content") action = menu.exec_(self.mapToGlobal(event.pos())) if action == copy_action: if clicked_widget is None: pass elif clicked_widget.objectName() == 'idinfo_button': self.idinfo.copy_mime() elif clicked_widget.objectName() == 'dataquality_button': self.dataqual.copy_mime() elif clicked_widget.objectName() == 'eainfo_button': self.eainfo.copy_mime() elif clicked_widget.objectName() == 'distinfo_button': self.distinfo.copy_mime() elif clicked_widget.objectName() == 'metainfo_button': self.metainfo.copy_mime() else: self.copy_mime() elif action == paste_action: self.paste_mime() elif action == clear_action: if clicked_widget is None: self.clear_widget() elif clicked_widget.objectName() == 'idinfo_button': self.idinfo.clear_widget() elif clicked_widget.objectName() == 'dataquality_button': self.dataqual.clear_widget() elif clicked_widget.objectName() == 'eainfo_button': self.eainfo.clear_widget() elif clicked_widget.objectName() == 'distinfo_button': self.distinfo.clear_widget() elif clicked_widget.objectName() == 'metainfo_button': self.metainfo.clear_widget() else: self.clear_widget() elif action == insert_before: self.parent_ui.insert_before(self) elif action == insert_after: self.parent_ui.insert_after(self) elif action == delete_action: self.parent_ui.delete_attr(self) elif help_action is not None and action == help_action: msg = QMessageBox(self) # msg.setTextFormat(Qt.RichText) msg.setText(clicked_widget.help_text) msg.setWindowTitle("Help") msg.show() self.in_context = False def to_xml(self): """ return an XML element with the contents of this widget, augmented with any original content not displayed on the widget if applicable. Returns ------- XML Element """ cur_index = self.ui.comboBox.currentIndex() if self.active: domain = self.domain.to_xml() elif self._domain_content[cur_index] is not None: domain = self._domain_content[cur_index] else: self.populate_domain_content(cur_index) domain = self.domain.to_xml() if self.ui.comboBox.currentIndex() == 0: attr = xml_utils.XMLNode(domain) attr.clear_children(tag='attrlabl') attr.clear_children(tag='attrdef') attr.clear_children(tag='attrdefs') attr = attr.to_xml() else: attr = xml_utils.xml_node('attr') attrdomv = xml_utils.xml_node('attrdomv', parent_node=attr) attrdomv.append(domain) attrlabl = xml_utils.xml_node('attrlabl', text=self.ui.fgdc_attrlabl.text(), parent_node=attr, index=0) attrdef = xml_utils.xml_node('attrdef', text=self.ui.fgdc_attrdef.toPlainText(), parent_node=attr, index=1) attrdefs = xml_utils.xml_node('attrdefs', text=self.ui.fgdc_attrdefs.text(), parent_node=attr, index=2) return attr def from_xml(self, attr): """ Populate widget with a representation of the passed XML element Parameters ---------- attr : XML Element Returns ------- None """ try: self.clear_widget() if attr.tag == 'attr': utils.populate_widget(self, attr) attr_dict = xml_utils.node_to_dict(attr) if not 'fgdc_attrdomv' in attr_dict.keys(): self.ui.comboBox.setCurrentIndex(3) elif 'fgdc_udom' in attr_dict['fgdc_attrdomv'].keys(): self.ui.comboBox.setCurrentIndex(3) self._domain_content[3] = attr.xpath('attrdomv/udom')[0] elif 'fgdc_rdom' in attr_dict['fgdc_attrdomv'].keys(): self.ui.comboBox.setCurrentIndex(1) self._domain_content[1] = attr.xpath('attrdomv/rdom')[0] elif 'fgdc_edom' in attr_dict['fgdc_attrdomv'].keys(): self.ui.comboBox.setCurrentIndex(0) self._domain_content[0] = attr elif 'fgdc_codesetd' in attr_dict['fgdc_attrdomv'].keys(): self.ui.comboBox.setCurrentIndex(2) self._domain_content[2] = attr.xpath( 'attrdomv/codesetd')[0] else: self.ui.comboBox.setCurrentIndex(3) else: print("The tag is not attr") except KeyError: pass
class LineItemObject(QGraphicsObject): # As per the ArrowItemObject def __init__(self, pti, ptf): super(LineItemObject, self).__init__() self.li = LineItem(pti, ptf, self) self.anim = QPropertyAnimation(self, b"thickness") def flash_undo(self): self.anim.setDuration(200) self.anim.setStartValue(2) self.anim.setKeyValueAt(0.5, 6) self.anim.setEndValue(0) self.anim.start() def flash_redo(self): self.anim.setDuration(200) self.anim.setStartValue(2) self.anim.setKeyValueAt(0.5, 4) self.anim.setEndValue(2) self.anim.start() @pyqtProperty(int) def thickness(self): return self.li.pen().width() @thickness.setter def thickness(self, value): self.li.setPen(QPen(Qt.red, value))
def visibility_animation(self, obj, visible): anim = QPropertyAnimation(obj, b'visible') anim.setDuration(0) if (visible): anim.setEndValue(1) else: anim.setEndValue(0) return anim
class BoardWidget(QWidget): def __init__(self, *args, **kwargs): QWidget.__init__(self, *args, **kwargs) self._config() def _config(self): self.cellSize = self.width() // 8 self.board = chess.Board() self.arrow_panel = QLabel(self) self.boardPixmap = QPixmap(":/boards/images/board.png") self.clickedAt = None self._create_pieces() self.listener = None self.piece_type_placing = None self.move_memory = [] self.arrows = [] self.refresh_board() self.paintEvent = lambda e: self._paint_background() self.arrow_panel.paintEvent = lambda e: self._paint_arrows() def resizeEvent(self, e): x, y = e.size().height(), e.size().width() self.cellSize = min(x, y) / 8 self.refresh_board() self.arrow_panel.resize(self.width(), self.height()) def _get_index(self, square): return square // 8, square % 8 def _get_coordinate(self, square): i, j = self._get_index(chess.square_mirror(square)) return j * self.cellSize, i * self.cellSize def _get_square(self, x, y): return chess.square_mirror( int(y // self.cellSize * 8 + (x // self.cellSize))) def _get_color_label(self, piece): return 'w' if piece.color == chess.WHITE else 'b' def _piece_path(self, piece): return f'://pieces//images//{self._get_color_label(piece) + piece.symbol().lower()}.png' def _paint_background(self): painter = QPainter(self) painter.drawPixmap(self.rect(), self.boardPixmap) def _paint_arrows(self): def transform(x, y, r, x0, y0): return QPoint(x0 + math.cos(r) * x - math.sin(r) * y, y0 + math.sin(r) * x + math.cos(r) * y) self.arrow_panel.setStyleSheet("background-color:transparent") self.arrow_panel.raise_() painter = QPainter(self.arrow_panel) # drawing the arrows # setting the brush for arrows brush = QBrush(QColor(100, 100, 100, 200)) painter.setBrush(brush) # enable antialising painter.setRenderHint(QPainter.Antialiasing) # remove the border painter.setPen(QPen(QColor(0, 0, 0, 0))) for arrow in self.arrows: if arrow.width <= 0: continue arrow_head_width = arrow.width * 3 * self.cellSize arrow_head_length = arrow_head_width * 0.8 x_from, y_from = self._get_coordinate(arrow.sq_from) x_to, y_to = self._get_coordinate(arrow.sq_to) distance = math.sqrt((y_from - y_to)**2 + (x_from - x_to)**2) width = arrow.width * self.cellSize angle = math.atan2(y_to - y_from, x_to - x_from) - math.pi / 2 x0 = x_from + self.cellSize // 2 y0 = y_from + self.cellSize // 2 # draw an arrow. first create a polygon which will receive some points polygon = QPolygon() polygon.append(transform(width / 2, 0, angle, x0, y0)) polygon.append( transform(width / 2, distance - arrow_head_length, angle, x0, y0)) polygon.append( transform(arrow_head_width / 2, distance - arrow_head_length, angle, x0, y0)) polygon.append(transform(0, distance, angle, x0, y0)) polygon.append( transform(-arrow_head_width / 2, distance - arrow_head_length, angle, x0, y0)) polygon.append( transform(-width / 2, distance - arrow_head_length, angle, x0, y0)) polygon.append(transform(-width / 2, 0, angle, x0, y0)) painter.drawPolygon(polygon) def _create_pieces(self): self.pieces = [] for square in range(64): x, y = self._get_coordinate(square) label = QLabel(self) label.move(x, y) label.setAlignment(Qt.AlignCenter) label.setStyleSheet("background-color:transparent;") self.pieces.append(label) def refresh_board(self): for square in chess.SQUARES: piece = self.board.piece_at(square) x, y = self._get_coordinate(square) self.pieces[square].move(x, y) self.pieces[square].resize(self.cellSize, self.cellSize) if piece is None: self.pieces[square].clear() continue self.pieces[square].setPixmap( QPixmap(self._piece_path(piece)).scaled( self.cellSize, self.cellSize, Qt.KeepAspectRatio, Qt.SmoothTransformation)) def set_piece_placed(self, piece_type=None): self.piece_type_placing = piece_type def mousePressEvent(self, e): print(self._get_square(e.x(), e.y())) # for placing a piece on the board if self.piece_type_placing is not None: square = self._get_square(e.x(), e.y()) if self.piece_type_placing == 0: self.board.remove_piece_at(square) else: if e.button() == Qt.LeftButton: self.board.set_piece_at( square, chess.Piece(self.piece_type_placing, chess.WHITE)) elif e.button() == Qt.RightButton: self.board.set_piece_at( square, chess.Piece(self.piece_type_placing, chess.BLACK)) self.notify_listener() self.refresh_board() # for normal move recognition elif e.button() == Qt.LeftButton: square = self._get_square(e.x(), e.y()) if self.clickedAt is None: # check if there is only a single valid move to this specific square (does consider promotions) if len( set(x.from_square + 64 * x.to_square for x in self.board.legal_moves if x.to_square == square)) == 1: move = [ x for x in self.board.legal_moves if x.to_square == square ][0] self.move_from_to(move.from_square, move.to_square) self.notify_listener() return # if there are multiple moves, select it and choose the piece next if len( set(x.from_square + 64 * x.to_square for x in self.board.legal_moves if x.to_square == square)) >= 1: self.clickedAt = square self.pieces[self.clickedAt].setStyleSheet( 'border: 5px solid gray; border-radius:5px; background-color:transparent;' ) return # dont select a square where the is an opponent piece if self.board.piece_at( square ) is not None and self.board.turn != self.board.piece_at( square).color: return # get the moves from that square moves = [ x for x in self.board.legal_moves if x.from_square == square ] # if there is no legal move, do not select it if len(moves) == 0: return # if there is only a single move, do it if len(moves) == 1: self.move_move(moves[0]) self.notify_listener() return # if there are multiple promotions, still do the move and request the promo piece if len( set(x.from_square + 64 * x.to_square for x in moves if x.from_square == square)) == 1: self.move_from_to(moves[0].from_square, moves[0].to_square) self.notify_listener() return # otherwise select the square self.clickedAt = square self.pieces[self.clickedAt].setStyleSheet( 'border: 5px solid gray; border-radius:5px; background-color:transparent;' ) return else: self.pieces[self.clickedAt].setStyleSheet( 'border: 0px; background-color:transparent;') if self.clickedAt == square: self.clickedAt = None return # check if the select square is a from or to square if self.board.piece_at( self.clickedAt) is None or self.board.piece_at( self.clickedAt).color != self.board.turn: if self.move_from_to(square, self.clickedAt): self.notify_listener() else: if self.move_from_to(self.clickedAt, square): self.notify_listener() self.clickedAt = None def show_promotion_dialog(self): # creates a promotion dialog to select a piece and return that # (0 for knight, 1 for bishop, 2 for rook, 3 for queen) d = QDialog() # no dialog bar d.setWindowFlags(Qt.FramelessWindowHint) layout = QGridLayout() layout.setContentsMargins(0, 0, 0, 0) layout.setHorizontalSpacing(0) layout.setVerticalSpacing(0) layout.setSpacing(0) # set default size d.resize(400, 400) d.move(self.x(), self.y()) promotionPiece = 0 def clickEvent(promoPiece): nonlocal promotionPiece promotionPiece = promoPiece d.close() turn = self.board.turn pieces = [ chess.Piece(chess.KNIGHT, turn), chess.Piece(chess.BISHOP, turn), chess.Piece(chess.ROOK, turn), chess.Piece(chess.QUEEN, turn) ] for i in range(4): # add some chess board style squareType = (i // 2 + i % 2 + 1) % 2 squareColor = ['#F0D9B7', '#B48866'][squareType] squareColorH = ['#F8E2BF', '#BB9F6D'][squareType] button = QPushButton() # select the icon + icon size button.setIcon(QIcon(self._piece_path(pieces[i]))) button.setIconSize(QSize(160, 160)) # fit the buttons button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) button.clicked.connect(lambda state, i=i: clickEvent(i)) # background color button.setStyleSheet(f""" QPushButton {{ background-color: {squareColor}; border: 0; }} QPushButton:hover {{ background-color: {squareColorH}; }} """) # adding to the grid layout layout.addWidget(button, i // 2, i % 2) d.setLayout(layout) # make sure it cannot be closed without selection d.setWindowModality(Qt.ApplicationModal) d.exec_() return promotionPiece def move_from_to(self, sq_from, sq_to): available_moves = [ x for x in self.board.legal_moves if x.from_square == sq_from and x.to_square == sq_to ] if len(available_moves) > 1: promo_piece = self.show_promotion_dialog() + 2 for k in available_moves: if k.promotion == promo_piece: available_moves[0] = k # handle promotion if len(available_moves) < 1: # no legal move return False move = available_moves[0] return self.move_move(move) def move_move(self, move): if move not in self.board.legal_moves: return False self.board.push(move) x_from, y_from = self._get_coordinate(move.from_square) x_to, y_to = self._get_coordinate(move.to_square) self.refresh_board() label = self.pieces[move.to_square] self.anim = QPropertyAnimation(label, b"pos") self.anim.setDuration(400) self.anim.setStartValue(QPoint(x_from, y_from)) self.anim.setEndValue(QPoint(x_to, y_to)) self.anim.setEasingCurve(QEasingCurve.InOutQuart) self.anim.start() # self.anim.finished.connect(self.notify_listener) self.move_memory = [] return True def undo_move(self): if len(self.board.move_stack) > 0: self.move_memory = [self.board.pop()] + self.move_memory self.refresh_board() self.notify_listener() def undo_all(self): while len(self.board.move_stack) > 0: self.move_memory = [self.board.pop()] + self.move_memory self.board.clear_stack() self.refresh_board() self.notify_listener() def redo_move(self, refresh=True): if len(self.move_memory) > 0: self.board.push(self.move_memory[0]) self.move_memory = self.move_memory[1:] if refresh: self.refresh_board() self.notify_listener() def redo_all(self): while len(self.move_memory) > 0: self.redo_move(refresh=False) self.refresh_board() self.notify_listener() def notify_listener(self): if self.listener is not None: self.listener(self.board.fen()) def listen(self, func): self.listener = func
class WindowNotify(QWidget, Ui_NotifyForm): SignalClosed = pyqtSignal() # 弹窗关闭信号 def __init__(self, title="", content="", timeout=5000, app=None, *args, **kwargs): super(WindowNotify, self).__init__(*args, **kwargs) self.setupUi(self) self.setTitle(title).setContent(content) self._timeout = timeout self.app = app self._init() def setTitle(self, title): if title: self.labelTitle.setText(title) return self def title(self): return self.labelTitle.text() def setContent(self, content): if content: self.labelContent.setText(content) return self def content(self): return self.labelContent.text() def setTimeout(self, timeout): if isinstance(timeout, int): self._timeout = timeout return self def timeout(self): return self._timeout # def onView(self): # print("onView") # webbrowser.open_new_tab("http://alyl.vip") def onClose(self): #点击关闭按钮时 print("onClose") self.isShow = False QTimer.singleShot(100, self.closeAnimation) #启动弹回动画 def _init(self): # 隐藏任务栏|去掉边框|顶层显示 self.setWindowFlags(Qt.Tool | Qt.X11BypassWindowManagerHint | Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint) # 关闭按钮事件 self.buttonClose.clicked.connect(self.onClose) # 点击查看按钮 # self.buttonView.clicked.connect(self.onView) # 是否在显示标志 self.isShow = True # 超时 self._timeouted = False # 桌面 self._desktop = QApplication.instance().desktop() # 窗口初始开始位置 self._startPos = QPoint( self._desktop.screenGeometry().width() - self.width() - 5, self._desktop.screenGeometry().height()) # 窗口弹出结束位置 self._endPos = QPoint( self._desktop.screenGeometry().width() - self.width() - 5, self._desktop.availableGeometry().height() - self.height() - 5) # 初始化位置到右下角 self.move(self._startPos) # 动画 self.animation = QPropertyAnimation(self, b"pos") self.animation.finished.connect(self.onAnimationEnd) self.animation.setDuration(1000) # 1s # 弹回定时器 self._timer = QTimer(self, timeout=self.closeAnimation) def show(self, title="", content="", timeout=5000): self._timer.stop() # 停止定时器,防止第二个弹出窗弹出时之前的定时器出问题 self.hide() # 先隐藏 self.move(self._startPos) # 初始化位置到右下角 super(WindowNotify, self).show() self.setTitle(title).setContent(content).setTimeout(timeout) return self def showAnimation(self): print("showAnimation isShow = True") # 显示动画 self.isShow = True self.animation.stop() #先停止之前的动画,重新开始 self.animation.setStartValue(self.pos()) self.animation.setEndValue(self._endPos) self.animation.start() # 弹出5秒后,如果没有焦点则弹回去 self._timer.start(self._timeout) # QTimer.singleShot(self._timeout, self.closeAnimation) def closeAnimation(self): print("closeAnimation hasFocus", self.hasFocus()) # 关闭动画 if self.hasFocus(): # 如果弹出后倒计时5秒后还有焦点存在则失去焦点后需要主动触发关闭 self._timeouted = True return # 如果有焦点则不关闭 self.isShow = False self.animation.stop() self.animation.setStartValue(self.pos()) self.animation.setEndValue(self._startPos) self.animation.start() def onAnimationEnd(self): # 动画结束 print("onAnimationEnd isShow", self.isShow) if not self.isShow: print("onAnimationEnd close()") self.close() print("onAnimationEnd stop timer") self._timer.stop() print("onAnimationEnd close and emit signal") self.SignalClosed.emit() def enterEvent(self, event): super(WindowNotify, self).enterEvent(event) # 设置焦点(好像没啥用,不过鼠标点击一下后,该方法就有用了) print("enterEvent setFocus Qt.MouseFocusReason") self.setFocus(Qt.MouseFocusReason) def leaveEvent(self, event): super(WindowNotify, self).leaveEvent(event) # 取消焦点 print("leaveEvent clearFocus") self.clearFocus() if self._timeouted: QTimer.singleShot(1000, self.closeAnimation)
class NotifyWidget(QWidget): def __init__(self): super().__init__() self.layout = QVBoxLayout(self) self.sub_widget = _NotifySubWidget(self) self.layout.addWidget(self.sub_widget) self.layout.setContentsMargins(0, 0, 0, 0) self._exit_shortcut = QShortcut(QKeySequence(Qt.Key_Escape), self) self._exit_shortcut.activated.connect(self.close) self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool) self.setAttribute(Qt.WA_TranslucentBackground) self.setAttribute(Qt.WA_MacAlwaysShowToolWindow) self.resize(width, height) self.move(QApplication.desktop().width() - self.width() - 20, 40) self.setLayout(self.layout) self._animation = QPropertyAnimation(self, b'windowOpacity') self._animation.setStartValue(0.8) self._animation.setKeyValueAt(0.4, 1) self._animation.setEndValue(0) self._animation.setDuration(5000) self._animation.finished.connect(self.close) def show(self): super().show() self._animation.start() def show_message(self, title, content, pixmap=None): if not self.isVisible(): self.show() self._animation.stop() self._animation.setCurrentTime(0) self._animation.start() self.sub_widget.set_title(title) self.sub_widget.set_content(content) pixmap = pixmap if pixmap else QPixmap(WINDOW_ICON) self.sub_widget.set_pixmap(pixmap) def enterEvent(self, event): self._animation.setCurrentTime(0)
def setup_ydhui(self): if self.biaotipos == 2: self.biaotipos = 1 self.edit22.hide() self.yuan2.hide() self.pushButton_19.hide() self.edit_suiji_size.hide() self.yuan3.hide() self.edit_suiji_num.hide() self.kuang.show() self.edit2.show() self.pushButton_18.show() self.edit.show() animation = QPropertyAnimation(self) animation.setTargetObject(self.biaoti_one) animation.setPropertyName(b"pos") animation.setStartValue(QPoint(615, 75)) animation.setEndValue((QPoint(375, 75))) animation.setDuration(300) animation.start()
def addRemovalAnimation(self, animGroup): # print(">>RemoveAnim") for phIdx in self.photoIdxsToRemove: item = self.photosInGrid[phIdx] anim = QPropertyAnimation(item.pixmap, "scale") anim.setDuration(self.shrinkDuration) anim.setEasingCurve(QEasingCurve.Linear) anim.setStartValue(1.0) anim.setEndValue(0.0) animGroup.addAnimation(anim) anim = QPropertyAnimation(item.pixmap, "pos") anim.setDuration(self.shrinkDuration) anim.setEasingCurve(QEasingCurve.Linear) startCoords = self.getCellTLCoords(item.gridRow, item.gridCol) endCoords = QPointF(startCoords.x()+self.cellSize.width()*item.xFactor, startCoords.y() + item.pixmap.pixmapSize.height() / 2) anim.setStartValue(startCoords) anim.setEndValue(endCoords) animGroup.addAnimation(anim)
def __init__(self, pti, ptf): super(LineItemObject, self).__init__() self.li = LineItem(pti, ptf, self) self.anim = QPropertyAnimation(self, b"thickness")
class FadeWidget(QWidget): """支持fade的QWidget""" def __init__(self): super().__init__() self.installEventFilter(self) def eventFilter(self, object, event): if event.type() == QEvent.WindowDeactivate: self.halfHide() elif event.type() == QEvent.WindowActivate: self.recoverHalfHide() return super().eventFilter(object, event) def halfHide(self): if self.windowOpacity() < 0.05: return None self.animation = QPropertyAnimation(self, b'windowOpacity') self.animation.setDuration(100) self.animation.setStartValue(1) self.animation.setEndValue(0.5) self.animation.start() def recoverHalfHide(self): if self.windowOpacity() > 0.95: return None self.animation = QPropertyAnimation(self, b'windowOpacity') self.animation.setDuration(100) self.animation.setStartValue(self.windowOpacity()) self.animation.setEndValue(1) self.animation.start() def hide(self): self.animation = QPropertyAnimation(self, b'windowOpacity') self.animation.setDuration(200) self.animation.setStartValue(1) self.animation.setEndValue(0) self.animation.finished.connect(super().hide) self.animation.start() def show(self): super().show() self.animation = QPropertyAnimation(self, b'windowOpacity') self.animation.setDuration(200) self.animation.setStartValue(0) self.animation.setEndValue(1) self.animation.start()
class WindowWithTitleBar(QFrame): def __init__(self, mainwidget, icon_name, parent=0): super(WindowWithTitleBar, self).__init__() self.setObjectName('WindowWithTitleBar') self.m_titlebar = Titlebar(self,icon_name) self.initWidgetsAndPack(mainwidget, self.m_titlebar) self.initStretch() self.initTipLabel(mainwidget) def initTipLabel(self, parent): """ 消息提示标签 :param parent: :return: """ self.tipLabel = QLabel(parent) self.tipLabel.setFixedSize(200, 40) self.tipLabel.setAlignment(Qt.AlignCenter) self.tipLabel.setWordWrap(True) self.tipLabel.setGeometry(self.width() / 2 - self.tipLabel.width() / 2, self.tipLabel.y(), self.tipLabel.width(), self.tipLabel.height()) self.tipLabel.hide() def showTip(self, text, color='#20c3ff'): if self.tipLabel is not None: self.tipLabel.show() self.tipLabel.setStyleSheet( "QLabel{background: %s;border:3px; color: #FFFFFF; border-radius: 5px}" % color) self.tipLabel.setText(text) eff = QGraphicsOpacityEffect(self) self.tipLabel.setGraphicsEffect(eff) self.animate = QPropertyAnimation(eff, "opacity") self.animate.setDuration(2000) self.animate.setStartValue(0.8) self.animate.setEndValue(0) self.animate.setEasingCurve(QEasingCurve.InCubic) self.animate.finished.connect(lambda: self.tipLabel.hide()) self.animate.start() def initWidgetsAndPack(self, mainwidget, titlebar): """ 将主体Widget和titleBar拼装起来 :param mainwidget: :param titlebar: :return: """ self.mainwidget = mainwidget self.resize(mainwidget.width(), mainwidget.height() + Titlebar.TITLEBAR_HEIGHT) self.setWindowFlags(Qt.FramelessWindowHint | self.windowFlags()) self.installEventFilter(titlebar) # 布局: titlbar在上主窗体在下 pLayout = QVBoxLayout(self) pLayout.addWidget(titlebar) pLayout.addWidget(mainwidget) pLayout.setSpacing(0) # 排列的几个widget为0间隔 pLayout.setContentsMargins(0, 0, 0, 0) self.setLayout(pLayout) def initStretch(self): """ 初始化拉伸功能 :return: """ self.setSupportStretch(True) self.m_isWindowMax = False self.m_stretchRectState = NO_SELECT self.m_isMousePressed = False self.setMinimumSize(self.mainwidget.minimumWidth(), self.mainwidget.minimumHeight() + Titlebar.TITLEBAR_HEIGHT) def getTitbar(self): return self.m_titlebar def setMinimumSize(self, width, height): """ 设置拉伸的最小Size :param width: :param height: :return: """ self.m_windowMinWidth = width self.m_windowMinHeight = height super(WindowWithTitleBar, self).setMinimumSize(width, height) def setWindowRadius(self, n_px): """ 圆边 :param n_px: 弧度 :return: """ objBitmap = QBitmap(self.size()) painter = QPainter(objBitmap) painter.setBrush(QColor(0, 0, 0)) painter.drawRoundedRect(self.rect(), n_px, n_px) self.setMask(objBitmap) def setBackgroundBorderColor(self, bgdcolor, bordercolor): self.setStyleSheet("WindowWithTitleBar{background:%s;border:3px solid %s}" % (bgdcolor, bordercolor)) def closeEvent(self, *args, **kwargs): self.mainwidget.close() def showEvent(self, event): self.calculateCurrentStrechRect() return super().showEvent(event) def calculateCurrentStrechRect(self): # 四个角Rect self.m_leftTopRect = QRect(0, 0, STRETCH_RECT_WIDTH, STRETCH_RECT_HEIGHT) self.m_leftBottomRect = QRect(0, self.height() - STRETCH_RECT_HEIGHT, STRETCH_RECT_WIDTH, STRETCH_RECT_WIDTH) self.m_rightTopRect = QRect(self.width() - STRETCH_RECT_WIDTH, 0, STRETCH_RECT_WIDTH, STRETCH_RECT_HEIGHT) self.m_rightBottomRect = QRect(self.width() - STRETCH_RECT_WIDTH, self.height() - STRETCH_RECT_HEIGHT, STRETCH_RECT_WIDTH, STRETCH_RECT_HEIGHT) # 四条边Rect self.m_topBorderRect = QRect(STRETCH_RECT_WIDTH, 0, self.width() - STRETCH_RECT_WIDTH * 2, STRETCH_RECT_HEIGHT) self.m_rightBorderRect = QRect(self.width() - STRETCH_RECT_WIDTH, STRETCH_RECT_HEIGHT, STRETCH_RECT_WIDTH, self.height() - STRETCH_RECT_HEIGHT * 2) self.m_bottomBorderRect = QRect(STRETCH_RECT_WIDTH, self.height() - STRETCH_RECT_HEIGHT, self.width() - STRETCH_RECT_WIDTH * 2, STRETCH_RECT_HEIGHT) self.m_leftBorderRect = QRect(0, STRETCH_RECT_HEIGHT, STRETCH_RECT_WIDTH, self.height() - STRETCH_RECT_HEIGHT * 2) def getCurrentStretchState(self, cursorPos): """ 根据鼠标的位置获取StretchState :param cursorPos: :return: """ if self.m_leftTopRect.contains(cursorPos): stretchState = LEFT_TOP_RECT elif self.m_rightTopRect.contains(cursorPos): stretchState = RIGHT_TOP_RECT elif self.m_rightBottomRect.contains(cursorPos): stretchState = RIGHT_BOTTOM_RECT elif self.m_leftBottomRect.contains(cursorPos): stretchState = LEFT_BOTTOM_RECT elif self.m_topBorderRect.contains(cursorPos): stretchState = TOP_BORDER elif self.m_rightBorderRect.contains(cursorPos): stretchState = RIGHT_BORDER elif self.m_bottomBorderRect.contains(cursorPos): stretchState = BOTTOM_BORDER elif self.m_leftBorderRect.contains(cursorPos): stretchState = LEFT_BORDER else: stretchState = NO_SELECT return stretchState def updateMouseStyle(self, stretchState): """ 根据stretchState刷新鼠标的样式 :param stretchState: :return: """ if stretchState == NO_SELECT: self.setCursor(Qt.ArrowCursor) elif stretchState == LEFT_TOP_RECT: self.setCursor(Qt.SizeFDiagCursor) elif stretchState == RIGHT_BOTTOM_RECT: self.setCursor(Qt.SizeFDiagCursor) elif stretchState == TOP_BORDER: self.setCursor(Qt.SizeVerCursor) elif stretchState == BOTTOM_BORDER: self.setCursor(Qt.SizeVerCursor) elif stretchState == RIGHT_TOP_RECT: self.setCursor(Qt.SizeBDiagCursor) elif stretchState == LEFT_BOTTOM_RECT: self.setCursor(Qt.SizeBDiagCursor) elif stretchState == LEFT_BORDER: self.setCursor(Qt.SizeHorCursor) elif stretchState == RIGHT_BORDER: self.setCursor(Qt.SizeHorCursor) else: self.setCursor(Qt.ArrowCursor) def mouseMoveEvent(self, event): """ 重写mouseMoveEvent事件,用于获取当前鼠标的位置,将位置传递给getCurrentStretchState方法, 得到当前鼠标的状态,然后调用updateMouseStyle对鼠标的样式进行更新 :param event: :return: """ # 如果窗口最大化是不能拉伸的 # 也不用更新鼠标样式 if (self.m_isWindowMax): return super().mouseMoveEvent(event) # 如果当前鼠标未按下,则根据当前鼠标的位置更新鼠标的状态及样式 if not self.m_isMousePressed: cursorPos = event.pos() # 根据当前鼠标的位置显示不同的样式 self.m_stretchRectState = self.getCurrentStretchState(cursorPos) self.updateMouseStyle(self.m_stretchRectState) # 如果当前鼠标左键已经按下,则记录下第二个点的位置,并更新窗口的大小 else: self.m_endPoint = self.mapToGlobal(event.pos()) self.updateWindowSize() return super().mouseMoveEvent(event) def mousePressEvent(self, event): # 当前鼠标进入了以上指定的8个区域,并且是左键按下时才开始进行窗口拉伸 if (self.m_stretchRectState != NO_SELECT and event.button() == Qt.LeftButton): self.m_isMousePressed = True # 记录下当前鼠标位置,为后面计算拉伸位置 self.m_startPoint = self.mapToGlobal(event.pos()) # 保存下拉伸前的窗口位置及大小 self.m_windowRectBeforeStretch = QRect(self.geometry().x(), self.geometry().y(), self.geometry().width(), self.geometry().height()) return super().mousePressEvent(event) def mouseReleaseEvent(self, event): """ 鼠标松开后意味之窗口拉伸结束,置标志位,并且重新计算用于拉伸的8个区域Rect :param event: :return: """ self.m_isMousePressed = False self.calculateCurrentStrechRect() return super().mouseReleaseEvent(event) def updateWindowSize(self): """ 拉伸窗口过程中,根据记录的坐标更新窗口大小 :return: """ windowRect = QRect(self.m_windowRectBeforeStretch.x(), self.m_windowRectBeforeStretch.y(), self.m_windowRectBeforeStretch.width(), self.m_windowRectBeforeStretch.height()) delValue_X = self.m_startPoint.x() - self.m_endPoint.x() delValue_Y = self.m_startPoint.y() - self.m_endPoint.y() if self.m_stretchRectState == LEFT_BORDER: topLeftPoint = windowRect.topLeft() topLeftPoint.setX(topLeftPoint.x() - delValue_X) windowRect.setTopLeft(topLeftPoint) elif self.m_stretchRectState == RIGHT_BORDER: bottomRightPoint = windowRect.bottomRight() bottomRightPoint.setX(bottomRightPoint.x() - delValue_X) windowRect.setBottomRight(bottomRightPoint) elif self.m_stretchRectState == TOP_BORDER: topLeftPoint = windowRect.topLeft() topLeftPoint.setY(topLeftPoint.y() - delValue_Y) windowRect.setTopLeft(topLeftPoint) elif self.m_stretchRectState == BOTTOM_BORDER: bottomRightPoint = windowRect.bottomRight() bottomRightPoint.setY(bottomRightPoint.y() - delValue_Y) windowRect.setBottomRight(bottomRightPoint) elif self.m_stretchRectState == LEFT_TOP_RECT: topLeftPoint = windowRect.topLeft() topLeftPoint.setX(topLeftPoint.x() - delValue_X) topLeftPoint.setY(topLeftPoint.y() - delValue_Y) windowRect.setTopLeft(topLeftPoint) elif self.m_stretchRectState == RIGHT_TOP_RECT: topRightPoint = windowRect.topRight() topRightPoint.setX(topRightPoint.x() - delValue_X) topRightPoint.setY(topRightPoint.y() - delValue_Y) windowRect.setTopRight(topRightPoint) elif self.m_stretchRectState == RIGHT_BOTTOM_RECT: bottomRightPoint = windowRect.bottomRight() bottomRightPoint.setX(bottomRightPoint.x() - delValue_X) bottomRightPoint.setY(bottomRightPoint.y() - delValue_Y) windowRect.setBottomRight(bottomRightPoint) elif self.m_stretchRectState == LEFT_BOTTOM_RECT: bottomLeftPoint = windowRect.bottomLeft() bottomLeftPoint.setX(bottomLeftPoint.x() - delValue_X) bottomLeftPoint.setY(bottomLeftPoint.y() - delValue_Y) windowRect.setBottomLeft(bottomLeftPoint) # 避免宽或高为零窗口显示有误,这里给窗口设置最小拉伸高度、宽度 if windowRect.width() < self.m_windowMinWidth: windowRect.setLeft(self.geometry().left()) windowRect.setWidth(self.m_windowMinWidth) if windowRect.height() < self.m_windowMinHeight: windowRect.setTop(self.geometry().top()) windowRect.setHeight(self.m_windowMinHeight) self.setGeometry(windowRect) def setSupportStretch(self, isSupportStretch): """ 设置当前窗口是否支持拉伸 :param isSupportStretch: :return: """ # 因为需要在鼠标未按下的情况下通过mouseMoveEvent事件捕捉鼠标位置,所以需要设置setMouseTracking为True(如果窗口支持拉伸) self.m_isSupportStretch = isSupportStretch self.setMouseTracking(isSupportStretch) # 这里对子控件也进行了设置,是因为如果不对子控件设置,当鼠标移动到子控件上时,不会发送mouseMoveEvent事件,也就获取不到当前鼠标位置,无法判断鼠标状态及显示样式了。 widgetList = self.findChildren(QWidget) for widget in widgetList: widget.setMouseTracking(isSupportStretch) if (self.m_titlebar is not None): # titleBar同理,也需要对自己及子控件进行调用setMouseTracking进行设置,见上方注释 # self.titleBar.setSupportStretch(isSupportStretch) pass def getSupportStretch(self): """ 返回当前窗口是否支持拉伸 :return: """ return self.m_isSupportStretch def setMaxEnable(self, isEnable): """ 最大化开闭 :param isEnable """ self.m_titlebar.setMaximumEnable(isEnable)
def __init__(self, stick: Stick, camera: Camera, parent: Optional[QGraphicsItem] = None): QGraphicsObject.__init__(self, parent) self.camera = camera self.stick = stick self.line = QLineF() self.gline = QGraphicsLineItem(self.line) self.stick_label_text = QGraphicsSimpleTextItem("0", self) self.stick_label_text.setFont(StickWidget.font) self.stick_label_text.setPos(self.line.p1() - QPoint(0, 24)) self.stick_label_text.setBrush(QBrush(QColor(0, 255, 0))) self.stick_label_text.hide() self.setZValue(10) self.mode = StickMode.Display self.btn_delete = Button("delete", "x", parent=self) self.btn_delete.setFlag(QGraphicsItem.ItemIgnoresTransformations, True) self.btn_delete.set_base_color([ButtonColor.RED]) self.btn_delete.setVisible(False) btn_size = max(int(np.linalg.norm(self.stick.top - self.stick.bottom) / 5.0), 15) self.btn_delete.set_height(12) self.btn_delete.clicked.connect(self.handle_btn_delete_clicked) self.btn_delete.setPos(self.line.p1() - QPointF(0.5 * self.btn_delete.boundingRect().width(), 1.1 * self.btn_delete.boundingRect().height())) self.btn_delete.set_opacity(0.7) self.top_handle = QGraphicsEllipseItem(0, 0, self.handle_size, self.handle_size, self) self.mid_handle = QGraphicsEllipseItem(0, 0, self.handle_size, self.handle_size, self) self.bottom_handle = QGraphicsEllipseItem(0, 0, self.handle_size, self.handle_size, self) self.top_handle.setAcceptedMouseButtons(Qt.NoButton) self.mid_handle.setAcceptedMouseButtons(Qt.NoButton) self.bottom_handle.setAcceptedMouseButtons(Qt.NoButton) self.top_handle.setBrush(self.handle_idle_brush) self.top_handle.setPen(self.handle_idle_pen) self.mid_handle.setBrush(self.handle_idle_brush) self.mid_handle.setPen(self.handle_idle_pen) self.bottom_handle.setBrush(self.handle_idle_brush) self.bottom_handle.setPen(self.handle_idle_pen) self.hovered_handle: Optional[QGraphicsRectItem] = None self.handles = [self.top_handle, self.mid_handle, self.bottom_handle] self.link_button = Button("link", "Link to...", parent=self) self.link_button.set_base_color([ButtonColor.GREEN]) self.link_button.set_height(12) self.link_button.set_label("Link", direction="vertical") self.link_button.fit_to_contents() self.link_button.clicked.connect(lambda: self.link_initiated.emit(self)) self.link_button.setVisible(False) self.link_button.setFlag(QGraphicsObject.ItemIgnoresTransformations, False) self.adjust_line() self.setAcceptHoverEvents(True) self.top_handle.setZValue(4) self.bottom_handle.setZValue(4) self.mid_handle.setZValue(4) self.top_handle.hide() self.mid_handle.hide() self.bottom_handle.hide() self.handle_mouse_offset = QPointF(0, 0) self.available_for_linking = False self.link_source = False self.current_highlight_color: QColor = StickWidget.normal_color self.highlighted = False self.frame_color: Optional[None] = self.normal_color self.is_linked = False self.is_master = True self.selected = False self.measured_height: int = -1 self.current_color = self.normal_color self.show_label = False self.highlight_animation = QPropertyAnimation(self, b"highlight_color") self.highlight_animation.valueChanged.connect(self.handle_highlight_animation_value_changed) self.deleting = False self.update_tooltip() self.show_measurements: bool = False self.proposed_snow_height: int = -1 self.zero_btn = Button("zero_btn", "0", parent=self) self.zero_btn.setFlag(QGraphicsItem.ItemIgnoresTransformations, True) self.zero_btn.setVisible(False) self.zero_btn.setPos(self.boundingRect().center() + QPointF(self.zero_btn.boundingRect().width() * -0.5, self.boundingRect().height() * 0.5)) self.zero_btn.clicked.connect(self.handle_zero)
def __init__(self): super(Robot, self).__init__() self.setFlag(self.ItemHasNoContents) self.torsoItem = RobotTorso(self) self.headItem = RobotHead(self.torsoItem) self.upperLeftArmItem = RobotLimb(self.torsoItem) self.lowerLeftArmItem = RobotLimb(self.upperLeftArmItem) self.upperRightArmItem = RobotLimb(self.torsoItem) self.lowerRightArmItem = RobotLimb(self.upperRightArmItem) self.upperRightLegItem = RobotLimb(self.torsoItem) self.lowerRightLegItem = RobotLimb(self.upperRightLegItem) self.upperLeftLegItem = RobotLimb(self.torsoItem) self.lowerLeftLegItem = RobotLimb(self.upperLeftLegItem) settings = ( # Item Position Rotation Scale # x y start end (self.headItem, 0, -18, 20, -20, 1.1), (self.upperLeftArmItem, -15, -10, 190, 180, 0), (self.lowerLeftArmItem, 30, 0, 50, 10, 0), (self.upperRightArmItem, 15, -10, 300, 310, 0), (self.lowerRightArmItem, 30, 0, 0, -70, 0), (self.upperRightLegItem, 10, 32, 40, 120, 0), (self.lowerRightLegItem, 30, 0, 10, 50, 0), (self.upperLeftLegItem, -10, 32, 150, 80, 0), (self.lowerLeftLegItem, 30, 0, 70, 10, 0), (self.torsoItem, 0, 0, 5, -20, 0), ) animation = QParallelAnimationGroup(self) for item, pos_x, pos_y, start_rot, end_rot, scale in settings: item.setPos(pos_x, pos_y) rot_animation = QPropertyAnimation(item, b"rotation") rot_animation.setStartValue(start_rot) rot_animation.setEndValue(end_rot) rot_animation.setEasingCurve(QEasingCurve.SineCurve) rot_animation.setDuration(2000) animation.addAnimation(rot_animation) if scale > 0: scale_animation = QPropertyAnimation(item, b"scale") scale_animation.setEndValue(scale) scale_animation.setEasingCurve(QEasingCurve.SineCurve) scale_animation.setDuration(2000) animation.addAnimation(scale_animation) animation.setLoopCount(-1) animation.start()
class MessageTip(QWidget): def __init__(self, msg: str): super().__init__() self.initUI(msg) def initUI(self, msg: str): self.setGeometry(300, 300, 350, 120) self.setStyleSheet("background-color: blue") self.setWindowFlags(Qt.FramelessWindowHint) layout = QHBoxLayout() layout.setContentsMargins(0, 0, 0, 0) label = QLabel() label.setText(msg) layout.addWidget(label) self.setLayout(layout) self.desktop = QDesktopWidget() self.move((self.desktop.availableGeometry().width() - self.width()), self.desktop.availableGeometry().height()) #初始化位置到右下角 self.showAnimation() def showAnimation(self): #显示弹出框动画 self.animation = QPropertyAnimation(self, b'pos') self.animation.setDuration(500) self.animation.setStartValue(QPoint(self.x(), self.y())) self.animation.setEndValue( QPoint( (self.desktop.availableGeometry().width() - self.width()), (self.desktop.availableGeometry().height() - self.height()))) self.animation.start() #设置弹出框1秒弹出,然后渐隐 self.remainTimer = QTimer() self.remainTimer.timeout.connect(self.closeAnimation) self.remainTimer.start(1000) #定时器3秒 def closeAnimation(self): #清除Timer和信号槽 self.remainTimer.stop() #self.disconnect(self.remainTimer,SLOT("closeAnimation()")) self.remainTimer.timeout.disconnect(self.closeAnimation) self.remainTimer.deleteLater() self.remainTimer = None #弹出框渐隐 self.animation = QPropertyAnimation(self, b"windowOpacity") self.animation.setDuration(1000) self.animation.setStartValue(1) self.animation.setEndValue(0) self.animation.start() #动画完成后清理 #self.connect(self.animation,SIGNAL("finished()"),SLOT("clearAll()")) self.animation.finished.connect(self.clearAll) def clearAll(self): self.close()
class ScreensharingToolbox(base_class, ui_class): exposedPixels = 3 def __init__(self, parent): super(ScreensharingToolbox, self).__init__(parent) with Resources.directory: self.setupUi() parent.installEventFilter(self) self.animation = QPropertyAnimation(self, 'pos') self.animation.setDuration(250) self.animation.setDirection(QPropertyAnimation.Forward) self.animation.setEasingCurve(QEasingCurve.Linear) # or OutCirc with 300ms self.retract_timer = QTimer(self) self.retract_timer.setInterval(3000) self.retract_timer.setSingleShot(True) self.retract_timer.timeout.connect(self.retract) self.resize(self.size().expandedTo(self.toolbox_layout.minimumSize())) def setupUi(self): super(ScreensharingToolbox, self).setupUi(self) # fix the SVG icons, as the generated code loads them as pixmaps, losing their ability to scale -Dan scale_icon = QIcon() scale_icon.addFile(Resources.get('icons/scale.svg'), mode=QIcon.Normal, state=QIcon.Off) viewonly_icon = QIcon() viewonly_icon.addFile(Resources.get('icons/viewonly.svg'), mode=QIcon.Normal, state=QIcon.Off) screenshot_icon = QIcon() screenshot_icon.addFile(Resources.get('icons/screenshot.svg'), mode=QIcon.Normal, state=QIcon.Off) fullscreen_icon = QIcon() fullscreen_icon.addFile(Resources.get('icons/fullscreen.svg'), mode=QIcon.Normal, state=QIcon.Off) fullscreen_icon.addFile(Resources.get('icons/fullscreen-exit.svg'), mode=QIcon.Normal, state=QIcon.On) fullscreen_icon.addFile(Resources.get('icons/fullscreen-exit.svg'), mode=QIcon.Active, state=QIcon.On) fullscreen_icon.addFile(Resources.get('icons/fullscreen-exit.svg'), mode=QIcon.Disabled, state=QIcon.On) fullscreen_icon.addFile(Resources.get('icons/fullscreen-exit.svg'), mode=QIcon.Selected, state=QIcon.On) minimize_icon = QIcon() minimize_icon.addFile(Resources.get('icons/minimize.svg'), mode=QIcon.Normal, state=QIcon.Off) minimize_icon.addFile(Resources.get('icons/minimize-active.svg'), mode=QIcon.Active, state=QIcon.Off) close_icon = QIcon() close_icon.addFile(Resources.get('icons/close.svg'), mode=QIcon.Normal, state=QIcon.Off) close_icon.addFile(Resources.get('icons/close-active.svg'), mode=QIcon.Active, state=QIcon.Off) self.scale_action.setIcon(scale_icon) self.viewonly_action.setIcon(viewonly_icon) self.screenshot_action.setIcon(screenshot_icon) self.fullscreen_action.setIcon(fullscreen_icon) self.minimize_action.setIcon(minimize_icon) self.close_action.setIcon(close_icon) self.scale_button.setIcon(scale_icon) self.viewonly_button.setIcon(viewonly_icon) self.screenshot_button.setIcon(screenshot_icon) self.fullscreen_button.setIcon(fullscreen_icon) self.minimize_button.setIcon(minimize_icon) self.close_button.setIcon(close_icon) self.scale_button.setDefaultAction(self.scale_action) self.viewonly_button.setDefaultAction(self.viewonly_action) self.screenshot_button.setDefaultAction(self.screenshot_action) self.fullscreen_button.setDefaultAction(self.fullscreen_action) self.minimize_button.setDefaultAction(self.minimize_action) self.close_button.setDefaultAction(self.close_action) self.color_depth_button.clear() self.color_depth_button.addItem('Default Color Depth', ServerDefault) self.color_depth_button.addItem('TrueColor (24 bits)', TrueColor) self.color_depth_button.addItem('HighColor (16 bits)', HighColor) self.color_depth_button.addItem('LowColor (8 bits)', LowColor) def eventFilter(self, watched, event): if watched is self.parent() and event.type() == QEvent.Resize: new_x = (watched.width() - self.width()) / 2 self.move(new_x, self.y()) self.animation.setStartValue(QPoint(new_x, -self.height() + self.exposedPixels)) self.animation.setEndValue(QPoint(new_x, 0)) return False def enterEvent(self, event): super(ScreensharingToolbox, self).enterEvent(event) self.retract_timer.stop() self.expose() def leaveEvent(self, event): super(ScreensharingToolbox, self).leaveEvent(event) self.retract_timer.start() def paintEvent(self, event): # make the widget style aware option = QStyleOption() option.initFrom(self) painter = QStylePainter(self) painter.drawPrimitive(QStyle.PE_Widget, option) def expose(self): if self.animation.state() == QPropertyAnimation.Running and self.animation.direction() == QPropertyAnimation.Forward: return elif self.animation.state() == QPropertyAnimation.Stopped and self.pos() == self.animation.endValue(): return self.animation.setDirection(QPropertyAnimation.Forward) self.animation.start() def retract(self): if self.animation.state() == QPropertyAnimation.Running and self.animation.direction() == QPropertyAnimation.Backward: return elif self.animation.state() == QPropertyAnimation.Stopped and self.pos() == self.animation.startValue(): return self.animation.setDirection(QPropertyAnimation.Backward) self.animation.start()
class StickWidget(QGraphicsObject): font: QFont = QFont("monospace", 32) delete_clicked = pyqtSignal(Stick) link_initiated = pyqtSignal('PyQt_PyObject') # Actually StickWidget link_accepted = pyqtSignal('PyQt_PyObject') hovered = pyqtSignal(['PyQt_PyObject', 'PyQt_PyObject']) stick_changed = pyqtSignal('PyQt_PyObject') sibling_changed = pyqtSignal(bool) right_clicked = pyqtSignal('PyQt_PyObject') handle_idle_brush = QBrush(QColor(0, 125, 125, 50)) handle_hover_brush = QBrush(QColor(125, 125, 0, 50)) handle_press_brush = QBrush(QColor(200, 200, 0, 0)) handle_idle_pen = QPen(QColor(0, 0, 0, 255)) handle_press_pen = QPen(QColor(200, 200, 0, 255)) handle_size = 20 normal_color = QColor(0, 200, 120) negative_color = QColor(200, 0, 0) positive_color = QColor(0, 200, 0) mismatched = pyqtSignal('PyQt_PyObject') misplaced = pyqtSignal('PyQt_PyObject') measurement_corrected = pyqtSignal('PyQt_PyObject') clearly_visible = pyqtSignal('PyQt_PyObject') zero_clicked = pyqtSignal('PyQt_PyObject') def __init__(self, stick: Stick, camera: Camera, parent: Optional[QGraphicsItem] = None): QGraphicsObject.__init__(self, parent) self.camera = camera self.stick = stick self.line = QLineF() self.gline = QGraphicsLineItem(self.line) self.stick_label_text = QGraphicsSimpleTextItem("0", self) self.stick_label_text.setFont(StickWidget.font) self.stick_label_text.setPos(self.line.p1() - QPoint(0, 24)) self.stick_label_text.setBrush(QBrush(QColor(0, 255, 0))) self.stick_label_text.hide() self.setZValue(10) self.mode = StickMode.Display self.btn_delete = Button("delete", "x", parent=self) self.btn_delete.setFlag(QGraphicsItem.ItemIgnoresTransformations, True) self.btn_delete.set_base_color([ButtonColor.RED]) self.btn_delete.setVisible(False) btn_size = max(int(np.linalg.norm(self.stick.top - self.stick.bottom) / 5.0), 15) self.btn_delete.set_height(12) self.btn_delete.clicked.connect(self.handle_btn_delete_clicked) self.btn_delete.setPos(self.line.p1() - QPointF(0.5 * self.btn_delete.boundingRect().width(), 1.1 * self.btn_delete.boundingRect().height())) self.btn_delete.set_opacity(0.7) self.top_handle = QGraphicsEllipseItem(0, 0, self.handle_size, self.handle_size, self) self.mid_handle = QGraphicsEllipseItem(0, 0, self.handle_size, self.handle_size, self) self.bottom_handle = QGraphicsEllipseItem(0, 0, self.handle_size, self.handle_size, self) self.top_handle.setAcceptedMouseButtons(Qt.NoButton) self.mid_handle.setAcceptedMouseButtons(Qt.NoButton) self.bottom_handle.setAcceptedMouseButtons(Qt.NoButton) self.top_handle.setBrush(self.handle_idle_brush) self.top_handle.setPen(self.handle_idle_pen) self.mid_handle.setBrush(self.handle_idle_brush) self.mid_handle.setPen(self.handle_idle_pen) self.bottom_handle.setBrush(self.handle_idle_brush) self.bottom_handle.setPen(self.handle_idle_pen) self.hovered_handle: Optional[QGraphicsRectItem] = None self.handles = [self.top_handle, self.mid_handle, self.bottom_handle] self.link_button = Button("link", "Link to...", parent=self) self.link_button.set_base_color([ButtonColor.GREEN]) self.link_button.set_height(12) self.link_button.set_label("Link", direction="vertical") self.link_button.fit_to_contents() self.link_button.clicked.connect(lambda: self.link_initiated.emit(self)) self.link_button.setVisible(False) self.link_button.setFlag(QGraphicsObject.ItemIgnoresTransformations, False) self.adjust_line() self.setAcceptHoverEvents(True) self.top_handle.setZValue(4) self.bottom_handle.setZValue(4) self.mid_handle.setZValue(4) self.top_handle.hide() self.mid_handle.hide() self.bottom_handle.hide() self.handle_mouse_offset = QPointF(0, 0) self.available_for_linking = False self.link_source = False self.current_highlight_color: QColor = StickWidget.normal_color self.highlighted = False self.frame_color: Optional[None] = self.normal_color self.is_linked = False self.is_master = True self.selected = False self.measured_height: int = -1 self.current_color = self.normal_color self.show_label = False self.highlight_animation = QPropertyAnimation(self, b"highlight_color") self.highlight_animation.valueChanged.connect(self.handle_highlight_animation_value_changed) self.deleting = False self.update_tooltip() self.show_measurements: bool = False self.proposed_snow_height: int = -1 self.zero_btn = Button("zero_btn", "0", parent=self) self.zero_btn.setFlag(QGraphicsItem.ItemIgnoresTransformations, True) self.zero_btn.setVisible(False) self.zero_btn.setPos(self.boundingRect().center() + QPointF(self.zero_btn.boundingRect().width() * -0.5, self.boundingRect().height() * 0.5)) self.zero_btn.clicked.connect(self.handle_zero) @pyqtSlot() def handle_btn_delete_clicked(self): self.delete_clicked.emit(self.stick) def prepare_for_deleting(self): self.deleting = True self.highlight_animation.stop() self.btn_delete.setParentItem(None) self.scene().removeItem(self.btn_delete) self.btn_delete.deleteLater() def paint(self, painter: QPainter, option: QStyleOptionGraphicsItem, widget: Optional[PyQt5.QtWidgets.QWidget] = ...): painter.setPen(QPen(self.current_color, 1.0)) brush = QBrush(self.current_highlight_color) pen = QPen(brush, 4) painter.setPen(pen) if self.highlighted: painter.fillRect(self.boundingRect(), QBrush(self.current_highlight_color)) if self.frame_color is not None and self.mode != StickMode.Edit and self.mode != StickMode.EditDelete: painter.setPen(QPen(self.frame_color, 4)) painter.drawRect(self.boundingRect()) pen = QPen(QColor(0, 255, 0, 255)) pen.setWidth(1.0) pen.setColor(QColor(255, 0, 255, 255)) pen.setStyle(Qt.DotLine) painter.setPen(pen) off = 10 painter.drawLine(self.line.p1() - QPointF(0, off), self.line.p1() + QPointF(0, off)) painter.drawLine(self.line.p1() - QPointF(off, 0), self.line.p1() + QPointF(off, 0)) painter.drawLine(self.line.p2() - QPointF(0, off), self.line.p2() + QPointF(0, off)) painter.drawLine(self.line.p2() - QPointF(off, 0), self.line.p2() + QPointF(off, 0)) pen.setStyle(Qt.SolidLine) pen.setColor(QColor(0, 255, 0, 255)) painter.setPen(pen) if self.mode != StickMode.EditDelete: pen.setWidth(2.0) br = painter.brush() painter.setPen(pen) painter.drawEllipse(self.line.p1(), 10, 10) painter.drawEllipse(self.line.p2(), 10, 10) painter.setBrush(br) if self.mode == StickMode.Measurement and self.proposed_snow_height >= 0: point = QPointF(self.boundingRect().x(), -self.proposed_snow_height + self.line.p2().y()) pen = QPen(QColor(200, 100, 0, 255), 3.0) painter.setPen(pen) painter.drawLine(point, point + QPointF(self.boundingRect().width(), 0.0)) if self.measured_height >= 0: vec = (self.stick.top - self.stick.bottom) / np.linalg.norm(self.stick.top - self.stick.bottom) dist_along_stick = self.measured_height / np.dot(np.array([0.0, -1.0]), vec) point = self.line.p2() + dist_along_stick * QPointF(vec[0], vec[1]) point = QPointF(self.boundingRect().x(), point.y()) pen = QPen(QColor(0, 100, 200, 255), 3.0) painter.setPen(pen) painter.drawLine(point, point + QPointF(self.boundingRect().width(), 0.0)) else: painter.drawLine(self.line.p1(), self.line.p2()) if self.selected: pen.setColor(QColor(255, 125, 0, 255)) pen.setStyle(Qt.DashLine) painter.setPen(pen) painter.drawRect(self.boundingRect().marginsAdded(QMarginsF(5, 5, 5, 5))) if self.show_measurements: painter.fillRect(self.stick_label_text.boundingRect().translated(self.stick_label_text.pos()), QBrush(QColor(0, 0, 0, 120))) def boundingRect(self) -> PyQt5.QtCore.QRectF: return self.gline.boundingRect().united(self.top_handle.boundingRect()).\ united(self.mid_handle.boundingRect()).united(self.bottom_handle.boundingRect()) def set_edit_mode(self, value: bool): if value: self.set_mode(StickMode.EditDelete) else: self.set_mode(StickMode.Display) def set_mode(self, mode: StickMode): if mode == StickMode.Display: self.btn_delete.setVisible(False) self.top_handle.setVisible(False) self.mid_handle.setVisible(False) self.bottom_handle.setVisible(False) self.link_button.setVisible(False) self.available_for_linking = False self.link_source = False self.zero_btn.setVisible(False) self.setVisible(self.stick.is_visible) elif mode == StickMode.EditDelete: self.set_mode(StickMode.Display) self.top_handle.setVisible(True) self.mid_handle.setVisible(True) self.bottom_handle.setVisible(True) self.available_for_linking = False self.link_source = False self.btn_delete.setVisible(True) elif mode == StickMode.LinkSource: self.set_mode(StickMode.Display) self.link_source = True self.available_for_linking = False self.link_button.setPos(self.boundingRect().topLeft()) self.link_button.set_width(int(self.boundingRect().width())) self.link_button.set_button_height(int(self.boundingRect().height())) self.link_button.adjust_text_to_button() elif mode == StickMode.LinkTarget: self.set_mode(StickMode.Display) self.link_source = False self.available_for_linking = True elif mode == StickMode.Edit: self.set_mode(StickMode.EditDelete) self.btn_delete.setVisible(False) elif mode == StickMode.Measurement: self.zero_btn.setVisible(True) self.setVisible(True) self.mode = mode self.update_tooltip() self.update() def mousePressEvent(self, event: QGraphicsSceneMouseEvent): if self.mode != StickMode.EditDelete: return if self.hovered_handle is None: return self.hovered_handle.setBrush(self.handle_press_brush) if self.hovered_handle == self.mid_handle: self.bottom_handle.setBrush(self.handle_press_brush) self.bottom_handle.setPen(self.handle_press_pen) self.bottom_handle.setOpacity(0.5) self.top_handle.setBrush(self.handle_press_brush) self.top_handle.setPen(self.handle_press_pen) self.top_handle.setOpacity(0.5) self.hovered_handle.setPen(self.handle_press_pen) self.hovered_handle.setOpacity(0.5) self.handle_mouse_offset = self.hovered_handle.rect().center() - event.pos() self.btn_delete.setVisible(False) def mouseReleaseEvent(self, event: QGraphicsSceneMouseEvent): if self.available_for_linking: self.link_accepted.emit(self) return if self.mode == StickMode.Measurement: old_snow = self.stick.snow_height_px self.measured_height = self.proposed_snow_height self.stick.set_snow_height_px(self.proposed_snow_height) if abs(old_snow - self.proposed_snow_height) > 0: self.measurement_corrected.emit(self) self.proposed_snow_height = -1 if self.mode != StickMode.EditDelete and self.mode != StickMode.Edit: return if self.hovered_handle is not None: self.hovered_handle.setBrush(self.handle_hover_brush) self.hovered_handle.setPen(self.handle_idle_pen) self.hovered_handle.setOpacity(1.0) if self.hovered_handle == self.mid_handle: self.bottom_handle.setBrush(self.handle_idle_brush) self.bottom_handle.setPen(self.handle_idle_pen) self.bottom_handle.setOpacity(1.0) self.top_handle.setBrush(self.handle_idle_brush) self.top_handle.setPen(self.handle_idle_pen) self.top_handle.setOpacity(1.0) self.stick_changed.emit(self) self.hovered_handle = None if self.mode == StickMode.EditDelete: self.btn_delete.setVisible(True) def mouseMoveEvent(self, event: QGraphicsSceneMouseEvent): if self.hovered_handle is None: return if self.hovered_handle == self.top_handle: self.line.setP1((event.pos() + self.handle_mouse_offset).toPoint()) elif self.hovered_handle == self.bottom_handle: self.line.setP2((event.pos() + self.handle_mouse_offset).toPoint()) else: displacement = event.pos() - event.lastPos() self.setPos(self.pos() + displacement) self.adjust_handles() self.adjust_stick() self.scene().update() def set_top(self, pos: QPoint): self.line.setP1(pos) self.adjust_handles() self.adjust_stick() self.scene().update() def set_bottom(self, pos: QPoint): self.line.setP2(pos) self.adjust_handles() self.adjust_stick() self.scene().update() def hoverEnterEvent(self, event: QGraphicsSceneHoverEvent): if self.available_for_linking: self.hovered.emit(True, self) elif self.link_source: self.link_button.setVisible(True) self.scene().update() def hoverLeaveEvent(self, event: QGraphicsSceneHoverEvent): for h in self.handles: h.setBrush(self.handle_idle_brush) self.hovered_handle = None if self.available_for_linking: self.hovered.emit(False, self) self.link_button.setVisible(False) self.proposed_snow_height = -1 self.scene().update() def hoverMoveEvent(self, event: QGraphicsSceneHoverEvent): if self.mode != StickMode.EditDelete and self.mode != StickMode.Edit and self.mode != StickMode.Measurement: return if self.mode == StickMode.Measurement: self.proposed_snow_height = max(self.line.p2().y() - event.pos().y(), 0) self.update() return hovered_handle = list(filter(lambda h: h.rect().contains(event.pos()), self.handles)) if len(hovered_handle) == 0: if self.hovered_handle is not None: self.hovered_handle.setBrush(self.handle_idle_brush) self.hovered_handle = None return if self.hovered_handle is not None and self.hovered_handle != hovered_handle[0]: self.hovered_handle.setBrush(self.handle_idle_brush) self.hovered_handle = hovered_handle[0] if self.hovered_handle == self.top_handle: self.top_handle.setBrush(self.handle_hover_brush) elif self.hovered_handle == self.bottom_handle: self.bottom_handle.setBrush(self.handle_hover_brush) else: self.mid_handle.setBrush(self.handle_hover_brush) self.scene().update() def adjust_stick(self): self.stick.top[0] = self.pos().x() + self.line.p1().x() self.stick.top[1] = self.pos().y() + self.line.p1().y() self.stick.bottom[0] = self.pos().x() + self.line.p2().x() self.stick.bottom[1] = self.pos().y() + self.line.p2().y() def adjust_handles(self): if self.line.p1().y() > self.line.p2().y(): p1, p2 = self.line.p1(), self.line.p2() self.line.setP1(p2) self.line.setP2(p1) if self.hovered_handle is not None: self.hovered_handle.setBrush(self.handle_idle_brush) self.hovered_handle.setPen(self.handle_idle_pen) self.hovered_handle = self.top_handle if self.hovered_handle == self.bottom_handle else self.bottom_handle self.hovered_handle.setBrush(self.handle_press_brush) self.hovered_handle.setPen(self.handle_press_pen) rect = self.top_handle.rect() rect.moveCenter(self.line.p1()) self.top_handle.setRect(rect) rect = self.bottom_handle.rect() rect.moveCenter(self.line.p2()) self.bottom_handle.setRect(rect) rect = self.mid_handle.rect() rect.moveCenter(self.line.center()) self.mid_handle.setRect(rect) self.btn_delete.setPos(self.top_handle.rect().center() - QPointF(self.btn_delete.boundingRect().width() / 2, self.btn_delete.boundingRect().height() + self.top_handle.boundingRect().height() / 2)) def set_available_for_linking(self, available: bool): self.available_for_linking = available def set_is_link_source(self, is_source: bool): self.link_source = is_source self.link_button.setPos(self.boundingRect().topLeft()) self.link_button.set_width(int(self.boundingRect().width())) self.link_button.set_button_height(int(self.boundingRect().height())) self.link_button.adjust_text_to_button() def set_frame_color(self, color: Optional[QColor]): self.frame_color = color if color is not None else self.normal_color self.update() def set_is_linked(self, value: bool): self.is_linked = value if not self.is_linked: self.set_frame_color(None) if self.available_for_linking: self.highlight(QColor(0, 255, 0, 100)) else: self.highlight(None) self.update_tooltip() def adjust_line(self): self.setPos(QPointF(0.5 * (self.stick.top[0] + self.stick.bottom[0]), 0.5 * (self.stick.top[1] + self.stick.bottom[1]))) vec = 0.5 * (self.stick.top - self.stick.bottom) self.line.setP1(QPointF(vec[0], vec[1])) self.line.setP2(-self.line.p1()) self.gline.setLine(self.line) self.adjust_handles() self.stick_label_text.setPos(self.line.p1() - QPointF(0.5 * self.stick_label_text.boundingRect().width(), 1.3 * self.stick_label_text.boundingRect().height())) self.update() def set_selected(self, selected: bool): self.selected = selected self.update() def is_selected(self) -> bool: return self.selected def set_snow_height(self, height: int): self.measured_height = height self.update() def border_normal(self): self.current_color = self.normal_color self.update() def border_positive(self): self.current_color = self.positive_color self.update() def border_negative(self): self.current_color = self.negative_color self.update() @pyqtProperty(QColor) def highlight_color(self) -> QColor: return self.current_highlight_color @highlight_color.setter def highlight_color(self, color: QColor): self.current_highlight_color = color def highlight(self, color: Optional[QColor], animated: bool = False): self.highlighted = color is not None if not animated or color is None: self.highlight_animation.stop() self.current_highlight_color = self.normal_color if color is None else color self.update() return self.highlight_animation.setStartValue(color) self.highlight_animation.setEndValue(color) self.highlight_animation.setKeyValueAt(0.5, color.darker()) self.highlight_animation.setDuration(2000) self.highlight_animation.setLoopCount(-1) self.highlight_animation.start() def handle_link_button_hovered(self, btn: Dict[str, Any]): self.link_button.setVisible(btn['hovered']) def handle_highlight_animation_value_changed(self, new: QColor): if not self.deleting: self.update(self.boundingRect().marginsAdded(QMarginsF(10, 10, 10, 10))) def contextMenuEvent(self, event: QGraphicsSceneContextMenuEvent) -> None: self.right_clicked.emit({'stick_widget': self}) def set_stick_label(self, label: str): self.stick.label = label self.stick_label_text.setText(label) self.update_tooltip() self.update() def get_stick_label(self) -> str: return self.stick.label def get_stick_length_cm(self) -> int: return self.stick.length_cm def set_stick_length_cm(self, length: int): self.stick.length_cm = length self.update_tooltip() self.update() def update_tooltip(self): if self.mode != StickMode.Display or self.mode == StickMode.Measurement: self.setToolTip("") return snow_txt = "Snow height: " if self.stick.snow_height_px >= 0: snow_txt += str(self.stick.snow_height_cm) + " cm" self.stick_label_text.setText(str(self.stick.snow_height_cm)) else: snow_txt = "not measured" self.stick_label_text.setVisible(False) self.stick_label_text.setText(self.stick.label) self.stick_label_text.setVisible(True) stick_view_text = '' role = '' if self.stick.alternative_view is not None: alt_view = self.stick.alternative_view role = " - primary" alt = "Secondary" if not self.stick.primary: role = " - secondary" alt = "Primary" stick_view_text = f'\n{alt} view: {alt_view.label} in {alt_view.camera_folder.name}\n' mark = '*' if self.stick.determines_quality else '' self.setToolTip(f'{mark}{self.stick.label}{role}{stick_view_text}\nLength: {self.stick.length_cm} cm\n{snow_txt}') def set_stick(self, stick: Stick): self.reset_d_btns() self.stick = stick self.adjust_line() self.adjust_handles() self.set_snow_height(stick.snow_height_px) self.update_tooltip() self.set_show_measurements(self.show_measurements) if self.mode == StickMode.Measurement: self.set_frame_color(QColor(200, 100, 0, 100) if not self.stick.is_visible else None) self.setVisible(True) self.clearly_visible_btn.setVisible(not self.stick.is_visible) else: self.setVisible(self.stick.is_visible) def set_show_measurements(self, show: bool): self.show_measurements = show if self.show_measurements: self.stick_label_text.setText(str(self.stick.snow_height_cm) if self.stick.snow_height_cm >= 0 else "n/a") else: self.stick_label_text.setText(self.stick.label) self.update() def handle_zero(self): self.measured_height = 0 self.stick.set_snow_height_px(0) self.measurement_corrected.emit(self) def reset_d_btns(self): self.zero_btn.set_default_state()
def timerEvent(self, *args, **kwargs): self.currentTime += 1 if self.currentTime >= self.timeout: self.timerMB.stop() self.timerMB.quit() a = QPropertyAnimation(self, "windowOpacity".encode()) #also b"opacity" a.setDuration(350) a.setStartValue(1) a.setEndValue(0) a.setEasingCurve(QEasingCurve.OutQuad) #QEasingCurve::OutBack a.start() self.done(0)
class Window(QMainWindow, Ui_MainWindow): def __init__(self, *args, **kwargs): super(Window, self).__init__(*args, **kwargs) self.setupUi(self) self.outani = QPropertyAnimation(self.widget, b"geometry") # 背后隐藏的控件 self.outani.setDuration(1000) # 1s self.outani.setEndValue(QRect(0, 30, 178, 681)) # 只是x坐标变化 # 移进去动画 self.inani = QPropertyAnimation(self.widget, b"geometry") # 背后隐藏的控件 self.inani.setDuration(1000) # 1s self.inani.setEndValue(QRect(0, -580, 178, 681)) self.inani.finished.connect(self.onFinish) # 绑定打开关闭事件 self.openButton.clicked.connect(self.onOpen) self.closeButton.clicked.connect(self.onClose) #打开文件 self.action.triggered.connect(self.openFile) self.action.setStatusTip('导入矩阵') self.action.setShortcut('Ctrl+Q') #退出系统 self.action_2.triggered.connect(self.close) self.action_2.setStatusTip('退出系统') self.action_2.setShortcut('Ctrl+E') #开发者信息 self.action_3.setStatusTip('唐伟泽 谢家柯 2016.12.3') def onOpen(self): # 设置按钮不可见 self.openButton.setVisible(False) self.widget.setVisible(True) # 背后的待拉出来的控件可见 self.graphicsView.setGeometry(QtCore.QRect(195, 1, 611, 641)) self.outani.start() # 开启动画效果 def onClose(self): self.outani.stop() # 如果移动到一半则停止 self.inani.start() # 退回去 def onFinish(self): # 关闭动画结束 self.widget.setVisible(False) self.openButton.setVisible(True) self.graphicsView.setGeometry(QtCore.QRect(0, 0, 801, 641)) def openFile(self): fileName1, filetype = QFileDialog.getOpenFileName( self, "选取文件", "/Users/Kelisiya/Desktop", "All Files (*);;Text Files (*.txt)") print(fileName1, filetype)
def setCurrentIndex(self, index: int, isNeedPopOut: bool = False, isShowNextWidgetDirectly: bool = True, duration: int = 250, easingCurve=QEasingCurve.OutQuad): """ 切换当前窗口 Parameters ---------- index: int 目标窗口下标 isNeedPopOut: bool 是否需要当前窗口的弹出动画 isShowNextWidgetDirectly: bool 是否需要在开始当前窗口的弹出动画前立即显示下一个小部件 duration: int 动画持续时间 easingCurve: QEasingCurve 动画插值方式 """ if index < 0 or index >= self.count(): raise Exception('下标错误') if index == self.currentIndex(): return if self.__currentAniGroup and self.__currentAniGroup.state( ) == QAbstractAnimation.Running: return # 记录需要切换到的窗口下标 self.__nextIndex = index self.__previousIndex = self.currentIndex() self.__previousWidget = self.currentWidget() # 记录弹入弹出方式 self.__isNeedPopOut = isNeedPopOut # 引用部件和动画 nextWidgetAni_dict = self.__widgetAni_list[index] currentWidgetAni_dict = self.__widgetAni_list[self.currentIndex()] self.__currentWidget = self.currentWidget() # type:QWidget self.__nextWidget = nextWidgetAni_dict['widget'] # type:QWidget currentPopUpAni = currentWidgetAni_dict['popUpAni'] nextPopUpAni = nextWidgetAni_dict['popUpAni'] self.__isNextWidgetNeedOpAni = nextWidgetAni_dict['isNeedOpacityAni'] self.__isCurrentWidgetNeedOpAni = currentWidgetAni_dict[ 'isNeedOpacityAni'] self.__currentAniGroup = currentWidgetAni_dict[ 'aniGroup'] if isNeedPopOut else nextWidgetAni_dict[ 'aniGroup'] # type:QParallelAnimationGroup # 设置透明度动画 if self.__isNextWidgetNeedOpAni: nextOpacityEffect = QGraphicsOpacityEffect(self) self.__nextOpacityAni = QPropertyAnimation(nextOpacityEffect, b'opacity') self.__nextWidget.setGraphicsEffect(nextOpacityEffect) self.__currentAniGroup.addAnimation(self.__nextOpacityAni) self.__setAnimation(self.__nextOpacityAni, 0, 1, duration) if self.__isCurrentWidgetNeedOpAni: currentOpacityEffect = QGraphicsOpacityEffect(self) self.__currentOpacityAni = QPropertyAnimation( currentOpacityEffect, b'opacity') self.__currentWidget.setGraphicsEffect(currentOpacityEffect) self.__currentAniGroup.addAnimation(self.__currentOpacityAni) self.__setAnimation(self.__currentOpacityAni, 1, 0, duration) # 当前窗口是否为弹入弹出式窗口 if isNeedPopOut: deltaX = currentWidgetAni_dict['deltaX'] deltaY = currentWidgetAni_dict['deltaY'] pos = self.__currentWidget.pos() + QPoint(deltaX, deltaY) # 当前窗口向内淡出 self.__setAnimation(currentPopUpAni, self.__currentWidget.pos(), pos, duration, easingCurve) # 显示下一窗口 self.__nextWidget.setVisible(isShowNextWidgetDirectly) else: # 设置下一个窗口的动画初始值 deltaX = nextWidgetAni_dict['deltaX'] deltaY = nextWidgetAni_dict['deltaY'] pos = self.__nextWidget.pos() + QPoint(deltaX, deltaY) self.__setAnimation(nextPopUpAni, pos, QPoint(self.__nextWidget.x(), 0), duration, easingCurve) # 直接切换当前窗口 super().setCurrentIndex(index) # 开始动画 self.__currentAniGroup.finished.connect(self.__aniFinishedSlot) self.__currentAniGroup.start() self.aniStart.emit()
def __init__(self, size, parent=None): super(PadNavigator, self).__init__(parent) self.form = Ui_Form() splash = SplashItem() splash.setZValue(1) pad = FlippablePad(size) flipRotation = QGraphicsRotation(pad) xRotation = QGraphicsRotation(pad) yRotation = QGraphicsRotation(pad) flipRotation.setAxis(Qt.YAxis) xRotation.setAxis(Qt.YAxis) yRotation.setAxis(Qt.XAxis) pad.setTransformations([flipRotation, xRotation, yRotation]) backItem = QGraphicsProxyWidget(pad) widget = QWidget() self.form.setupUi(widget) self.form.hostName.setFocus() backItem.setWidget(widget) backItem.setVisible(False) backItem.setFocus() backItem.setCacheMode(QGraphicsItem.ItemCoordinateCache) r = backItem.rect() backItem.setTransform(QTransform().rotate(180, Qt.YAxis).translate( -r.width() / 2, -r.height() / 2)) selectionItem = RoundRectItem(QRectF(-60, -60, 120, 120), QColor(Qt.gray), pad) selectionItem.setZValue(0.5) smoothSplashMove = QPropertyAnimation(splash, b"y") smoothSplashOpacity = QPropertyAnimation(splash, b"opacity") smoothSplashMove.setEasingCurve(QEasingCurve.InQuad) smoothSplashMove.setDuration(250) smoothSplashOpacity.setDuration(250) smoothXSelection = QPropertyAnimation(selectionItem, b"x") smoothYSelection = QPropertyAnimation(selectionItem, b"y") smoothXRotation = QPropertyAnimation(xRotation, b"angle") smoothYRotation = QPropertyAnimation(yRotation, b"angle") smoothXSelection.setDuration(125) smoothYSelection.setDuration(125) smoothXRotation.setDuration(125) smoothYRotation.setDuration(125) smoothXSelection.setEasingCurve(QEasingCurve.InOutQuad) smoothYSelection.setEasingCurve(QEasingCurve.InOutQuad) smoothXRotation.setEasingCurve(QEasingCurve.InOutQuad) smoothYRotation.setEasingCurve(QEasingCurve.InOutQuad) smoothFlipRotation = QPropertyAnimation(flipRotation, b"angle") smoothFlipScale = QPropertyAnimation(pad, b"scale") smoothFlipXRotation = QPropertyAnimation(xRotation, b"angle") smoothFlipYRotation = QPropertyAnimation(yRotation, b"angle") flipAnimation = QParallelAnimationGroup(self) smoothFlipScale.setDuration(500) smoothFlipRotation.setDuration(500) smoothFlipXRotation.setDuration(500) smoothFlipYRotation.setDuration(500) smoothFlipScale.setEasingCurve(QEasingCurve.InOutQuad) smoothFlipRotation.setEasingCurve(QEasingCurve.InOutQuad) smoothFlipXRotation.setEasingCurve(QEasingCurve.InOutQuad) smoothFlipYRotation.setEasingCurve(QEasingCurve.InOutQuad) smoothFlipScale.setKeyValueAt(0, 1.0) smoothFlipScale.setKeyValueAt(0.5, 0.7) smoothFlipScale.setKeyValueAt(1, 1.0) flipAnimation.addAnimation(smoothFlipRotation) flipAnimation.addAnimation(smoothFlipScale) flipAnimation.addAnimation(smoothFlipXRotation) flipAnimation.addAnimation(smoothFlipYRotation) setVariablesSequence = QSequentialAnimationGroup() setFillAnimation = QPropertyAnimation(pad, b"fill") setBackItemVisibleAnimation = QPropertyAnimation(backItem, b"visible") setSelectionItemVisibleAnimation = QPropertyAnimation( selectionItem, b"visible") setFillAnimation.setDuration(0) setBackItemVisibleAnimation.setDuration(0) setSelectionItemVisibleAnimation.setDuration(0) setVariablesSequence.addPause(250) setVariablesSequence.addAnimation(setBackItemVisibleAnimation) setVariablesSequence.addAnimation(setSelectionItemVisibleAnimation) setVariablesSequence.addAnimation(setFillAnimation) flipAnimation.addAnimation(setVariablesSequence) stateMachine = QStateMachine(self) splashState = QState(stateMachine) frontState = QState(stateMachine) historyState = QHistoryState(frontState) backState = QState(stateMachine) frontState.assignProperty(pad, "fill", False) frontState.assignProperty(splash, "opacity", 0.0) frontState.assignProperty(backItem, "visible", False) frontState.assignProperty(flipRotation, "angle", 0.0) frontState.assignProperty(selectionItem, "visible", True) backState.assignProperty(pad, "fill", True) backState.assignProperty(backItem, "visible", True) backState.assignProperty(xRotation, "angle", 0.0) backState.assignProperty(yRotation, "angle", 0.0) backState.assignProperty(flipRotation, "angle", 180.0) backState.assignProperty(selectionItem, "visible", False) stateMachine.addDefaultAnimation(smoothXRotation) stateMachine.addDefaultAnimation(smoothYRotation) stateMachine.addDefaultAnimation(smoothXSelection) stateMachine.addDefaultAnimation(smoothYSelection) stateMachine.setInitialState(splashState) anyKeyTransition = QEventTransition(self, QEvent.KeyPress, splashState) anyKeyTransition.setTargetState(frontState) anyKeyTransition.addAnimation(smoothSplashMove) anyKeyTransition.addAnimation(smoothSplashOpacity) enterTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Enter, backState) returnTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Return, backState) backEnterTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Enter, frontState) backReturnTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Return, frontState) enterTransition.setTargetState(historyState) returnTransition.setTargetState(historyState) backEnterTransition.setTargetState(backState) backReturnTransition.setTargetState(backState) enterTransition.addAnimation(flipAnimation) returnTransition.addAnimation(flipAnimation) backEnterTransition.addAnimation(flipAnimation) backReturnTransition.addAnimation(flipAnimation) columns = size.width() rows = size.height() stateGrid = [] for y in range(rows): stateGrid.append([QState(frontState) for _ in range(columns)]) frontState.setInitialState(stateGrid[0][0]) selectionItem.setPos(pad.iconAt(0, 0).pos()) for y in range(rows): for x in range(columns): state = stateGrid[y][x] rightTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Right, state) leftTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Left, state) downTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Down, state) upTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Up, state) rightTransition.setTargetState(stateGrid[y][(x + 1) % columns]) leftTransition.setTargetState( stateGrid[y][((x - 1) + columns) % columns]) downTransition.setTargetState(stateGrid[(y + 1) % rows][x]) upTransition.setTargetState(stateGrid[((y - 1) + rows) % rows][x]) icon = pad.iconAt(x, y) state.assignProperty(xRotation, "angle", -icon.x() / 6.0) state.assignProperty(yRotation, "angle", icon.y() / 6.0) state.assignProperty(selectionItem, "x", icon.x()) state.assignProperty(selectionItem, "y", icon.y()) frontState.assignProperty(icon, "visible", True) backState.assignProperty(icon, "visible", False) setIconVisibleAnimation = QPropertyAnimation(icon, b"visible") setIconVisibleAnimation.setDuration(0) setVariablesSequence.addAnimation(setIconVisibleAnimation) scene = QGraphicsScene(self) scene.setBackgroundBrush( QBrush(QPixmap(":/images/blue_angle_swirl.jpg"))) scene.setItemIndexMethod(QGraphicsScene.NoIndex) scene.addItem(pad) scene.setSceneRect(scene.itemsBoundingRect()) self.setScene(scene) sbr = splash.boundingRect() splash.setPos(-sbr.width() / 2, scene.sceneRect().top() - 2) frontState.assignProperty(splash, "y", splash.y() - 100.0) scene.addItem(splash) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setMinimumSize(50, 50) self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate) self.setCacheMode(QGraphicsView.CacheBackground) self.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.TextAntialiasing) if QGLFormat.hasOpenGL(): self.setViewport(QGLWidget(QGLFormat(QGL.SampleBuffers))) stateMachine.start()
def __init__(self, pt): super(TickItemObject, self).__init__() self.ti = TickItem(pt, self) self.anim = QPropertyAnimation(self, b"thickness")
def __init__(self, parent=None): super(Preferences, self).__init__(parent) # Main container # This contains a grid main_box = QVBoxLayout(self) main_box.setContentsMargins(200, 50, 200, 100) # The grid contains two containers # left container and right container grid = QGridLayout() # Left Container left_container = QVBoxLayout() left_container.setContentsMargins(0, 0, 0, 0) # General group_gral = QGroupBox(self.tr("General")) box_gral = QVBoxLayout(group_gral) # Updates btn_updates = QPushButton(self.tr("Check for updates")) box_gral.addWidget(btn_updates) # Language group_language = QGroupBox(self.tr("Language")) box = QVBoxLayout(group_language) # Find .qm files in language path available_langs = file_manager.get_files_from_folder( settings.LANGUAGE_PATH) languages = ["English"] + available_langs self._combo_lang = QComboBox() box.addWidget(self._combo_lang) self._combo_lang.addItems(languages) self._combo_lang.currentIndexChanged[int].connect( self._change_lang) if PSetting.LANGUAGE: self._combo_lang.setCurrentText(PSetting.LANGUAGE) box.addWidget(QLabel(self.tr("(Requires restart)"))) # Add widgets left_container.addWidget(group_gral) left_container.addWidget(group_language) left_container.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Expanding)) # Right Container right_container = QVBoxLayout() right_container.setContentsMargins(0, 0, 0, 0) # Editor editor_group = QGroupBox(self.tr("Editor Configurations")) box_editor = QHBoxLayout(editor_group) # Current line self._highlight_current_line = QCheckBox( self.tr("Highlight Current Line")) self._highlight_current_line.setChecked( PSetting.HIGHLIGHT_CURRENT_LINE) self._highlight_current_line.stateChanged[int].connect( self.__current_line_value_changed) box_editor.addWidget(self._highlight_current_line) # Matching paren self._matching_paren = QCheckBox(self.tr("Matching Parenthesis")) self._matching_paren.setChecked( PSetting.MATCHING_PARENTHESIS) self._matching_paren.stateChanged[int].connect( self.__set_enabled_matching_parenthesis) box_editor.addWidget(self._matching_paren) # Font group font_group = QGroupBox(self.tr("Font")) font_grid = QGridLayout(font_group) font_grid.addWidget(QLabel(self.tr("Family")), 0, 0) self._combo_font = QFontComboBox() self._combo_font.setCurrentFont(PSetting.FONT) font_grid.addWidget(self._combo_font, 0, 1) font_grid.addWidget(QLabel(self.tr("Point Size")), 1, 0) self._combo_font_size = QComboBox() fdb = QFontDatabase() combo_sizes = fdb.pointSizes(PSetting.FONT.family()) current_size_index = combo_sizes.index( PSetting.FONT.pointSize()) self._combo_font_size.addItems([str(f) for f in combo_sizes]) self._combo_font_size.setCurrentIndex(current_size_index) font_grid.addWidget(self._combo_font_size, 1, 1) right_container.addWidget(editor_group) right_container.addWidget(font_group) right_container.addItem(QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Expanding)) # Add widgets grid.addLayout(left_container, 0, 0) grid.addLayout(right_container, 0, 1) main_box.addLayout(grid) # Button close and reset hbox = QHBoxLayout() hbox.setSpacing(20) hbox.addItem(QSpacerItem(1, 0, QSizePolicy.Expanding)) btn_cancel = QPushButton(self.tr("Back")) hbox.addWidget(btn_cancel) btn_reset = QPushButton(self.tr("Reset Configurations")) hbox.addWidget(btn_reset) main_box.addLayout(hbox) # Overlay self.overlay = overlay_widget.OverlayWidget(self) self.overlay.hide() # Effect and animations self.effect = QGraphicsOpacityEffect() self.setGraphicsEffect(self.effect) duration, x = 180, 150 # Animation duration # Animation start # Opacity animation self.opacity_animation_s = QPropertyAnimation(self.effect, b"opacity") self.opacity_animation_s.setDuration(duration) self.opacity_animation_s.setStartValue(0.0) self.opacity_animation_s.setEndValue(1.0) # X animation self.x_animation_s = QPropertyAnimation(self, b"geometry") self.x_animation_s.setDuration(duration) self.x_animation_s.setStartValue(QRect(x, 0, parent.width(), parent.height())) self.x_animation_s.setEndValue(QRect(0, 0, parent.width(), parent.height())) # Animation end # Opacity animation self.opacity_animation_e = QPropertyAnimation(self.effect, b"opacity") self.opacity_animation_e.setDuration(duration) self.opacity_animation_e.setStartValue(1.0) self.opacity_animation_e.setEndValue(0.0) # X animation self.x_animation_e = QPropertyAnimation(self, b"geometry") self.x_animation_e.setDuration(duration) self.x_animation_e.setStartValue(QRect(0, 0, parent.width(), parent.height())) self.x_animation_e.setEndValue(QRect(-x, 0, parent.width(), parent.height())) # Group animation start self.group_animation_s = QParallelAnimationGroup() self.group_animation_s.addAnimation(self.opacity_animation_s) self.group_animation_s.addAnimation(self.x_animation_s) # Group animation end self.group_animation_e = QParallelAnimationGroup() self.group_animation_e.addAnimation(self.opacity_animation_e) self.group_animation_e.addAnimation(self.x_animation_e) # Connections self.group_animation_e.finished.connect( self._on_group_animation_finished) btn_cancel.clicked.connect(self.close) btn_reset.clicked.connect(self._reset_settings) btn_updates.clicked.connect(self._check_for_updates) # self.thread.finished.connect(self._on_thread_finished) self._combo_font.currentFontChanged.connect( self._change_font) self._combo_font_size.currentTextChanged.connect( self._change_font_size)
def __init__(self, size, parent=None): super(PadNavigator, self).__init__(parent) self.form = Ui_Form() splash = SplashItem() splash.setZValue(1) pad = FlippablePad(size) flipRotation = QGraphicsRotation(pad) xRotation = QGraphicsRotation(pad) yRotation = QGraphicsRotation(pad) flipRotation.setAxis(Qt.YAxis) xRotation.setAxis(Qt.YAxis) yRotation.setAxis(Qt.XAxis) pad.setTransformations([flipRotation, xRotation, yRotation]) backItem = QGraphicsProxyWidget(pad) widget = QWidget() self.form.setupUi(widget) self.form.hostName.setFocus() backItem.setWidget(widget) backItem.setVisible(False) backItem.setFocus() backItem.setCacheMode(QGraphicsItem.ItemCoordinateCache) r = backItem.rect() backItem.setTransform(QTransform().rotate(180, Qt.YAxis).translate(-r.width()/2, -r.height()/2)) selectionItem = RoundRectItem(QRectF(-60, -60, 120, 120), QColor(Qt.gray), pad) selectionItem.setZValue(0.5) smoothSplashMove = QPropertyAnimation(splash, b'y') smoothSplashOpacity = QPropertyAnimation(splash, b'opacity') smoothSplashMove.setEasingCurve(QEasingCurve.InQuad) smoothSplashMove.setDuration(250) smoothSplashOpacity.setDuration(250) smoothXSelection = QPropertyAnimation(selectionItem, b'x') smoothYSelection = QPropertyAnimation(selectionItem, b'y') smoothXRotation = QPropertyAnimation(xRotation, b'angle') smoothYRotation = QPropertyAnimation(yRotation, b'angle') smoothXSelection.setDuration(125) smoothYSelection.setDuration(125) smoothXRotation.setDuration(125) smoothYRotation.setDuration(125) smoothXSelection.setEasingCurve(QEasingCurve.InOutQuad) smoothYSelection.setEasingCurve(QEasingCurve.InOutQuad) smoothXRotation.setEasingCurve(QEasingCurve.InOutQuad) smoothYRotation.setEasingCurve(QEasingCurve.InOutQuad) smoothFlipRotation = QPropertyAnimation(flipRotation, b'angle') smoothFlipScale = QPropertyAnimation(pad, b'scale') smoothFlipXRotation = QPropertyAnimation(xRotation, b'angle') smoothFlipYRotation = QPropertyAnimation(yRotation, b'angle') flipAnimation = QParallelAnimationGroup(self) smoothFlipScale.setDuration(500) smoothFlipRotation.setDuration(500) smoothFlipXRotation.setDuration(500) smoothFlipYRotation.setDuration(500) smoothFlipScale.setEasingCurve(QEasingCurve.InOutQuad) smoothFlipRotation.setEasingCurve(QEasingCurve.InOutQuad) smoothFlipXRotation.setEasingCurve(QEasingCurve.InOutQuad) smoothFlipYRotation.setEasingCurve(QEasingCurve.InOutQuad) smoothFlipScale.setKeyValueAt(0, 1.0) smoothFlipScale.setKeyValueAt(0.5, 0.7) smoothFlipScale.setKeyValueAt(1, 1.0) flipAnimation.addAnimation(smoothFlipRotation) flipAnimation.addAnimation(smoothFlipScale) flipAnimation.addAnimation(smoothFlipXRotation) flipAnimation.addAnimation(smoothFlipYRotation) setVariablesSequence = QSequentialAnimationGroup() setFillAnimation = QPropertyAnimation(pad, b'fill') setBackItemVisibleAnimation = QPropertyAnimation(backItem, b'visible') setSelectionItemVisibleAnimation = QPropertyAnimation(selectionItem, b'visible') setFillAnimation.setDuration(0) setBackItemVisibleAnimation.setDuration(0) setSelectionItemVisibleAnimation.setDuration(0) setVariablesSequence.addPause(250) setVariablesSequence.addAnimation(setBackItemVisibleAnimation) setVariablesSequence.addAnimation(setSelectionItemVisibleAnimation) setVariablesSequence.addAnimation(setFillAnimation) flipAnimation.addAnimation(setVariablesSequence) stateMachine = QStateMachine(self) splashState = QState(stateMachine) frontState = QState(stateMachine) historyState = QHistoryState(frontState) backState = QState(stateMachine) frontState.assignProperty(pad, "fill", False) frontState.assignProperty(splash, "opacity", 0.0) frontState.assignProperty(backItem, "visible", False) frontState.assignProperty(flipRotation, "angle", 0.0) frontState.assignProperty(selectionItem, "visible", True) backState.assignProperty(pad, "fill", True) backState.assignProperty(backItem, "visible", True) backState.assignProperty(xRotation, "angle", 0.0) backState.assignProperty(yRotation, "angle", 0.0) backState.assignProperty(flipRotation, "angle", 180.0) backState.assignProperty(selectionItem, "visible", False) stateMachine.addDefaultAnimation(smoothXRotation) stateMachine.addDefaultAnimation(smoothYRotation) stateMachine.addDefaultAnimation(smoothXSelection) stateMachine.addDefaultAnimation(smoothYSelection) stateMachine.setInitialState(splashState) anyKeyTransition = QEventTransition(self, QEvent.KeyPress, splashState) anyKeyTransition.setTargetState(frontState) anyKeyTransition.addAnimation(smoothSplashMove) anyKeyTransition.addAnimation(smoothSplashOpacity) enterTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Enter, backState) returnTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Return, backState) backEnterTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Enter, frontState) backReturnTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Return, frontState) enterTransition.setTargetState(historyState) returnTransition.setTargetState(historyState) backEnterTransition.setTargetState(backState) backReturnTransition.setTargetState(backState) enterTransition.addAnimation(flipAnimation) returnTransition.addAnimation(flipAnimation) backEnterTransition.addAnimation(flipAnimation) backReturnTransition.addAnimation(flipAnimation) columns = size.width() rows = size.height() stateGrid = [] for y in range(rows): stateGrid.append([QState(frontState) for _ in range(columns)]) frontState.setInitialState(stateGrid[0][0]) selectionItem.setPos(pad.iconAt(0, 0).pos()) for y in range(rows): for x in range(columns): state = stateGrid[y][x] rightTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Right, state) leftTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Left, state) downTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Down, state) upTransition = QKeyEventTransition(self, QEvent.KeyPress, Qt.Key_Up, state) rightTransition.setTargetState(stateGrid[y][(x + 1) % columns]) leftTransition.setTargetState(stateGrid[y][((x - 1) + columns) % columns]) downTransition.setTargetState(stateGrid[(y + 1) % rows][x]) upTransition.setTargetState(stateGrid[((y - 1) + rows) % rows][x]) icon = pad.iconAt(x, y) state.assignProperty(xRotation, "angle", -icon.x() / 6.0) state.assignProperty(yRotation, "angle", icon.y() / 6.0) state.assignProperty(selectionItem, "x", icon.x()) state.assignProperty(selectionItem, "y", icon.y()) frontState.assignProperty(icon, "visible", True) backState.assignProperty(icon, "visible", False) setIconVisibleAnimation = QPropertyAnimation(icon, b'visible') setIconVisibleAnimation.setDuration(0) setVariablesSequence.addAnimation(setIconVisibleAnimation) scene = QGraphicsScene(self) scene.setBackgroundBrush(QBrush(QPixmap(":/images/blue_angle_swirl.jpg"))) scene.setItemIndexMethod(QGraphicsScene.NoIndex) scene.addItem(pad) scene.setSceneRect(scene.itemsBoundingRect()) self.setScene(scene) sbr = splash.boundingRect() splash.setPos(-sbr.width() / 2, scene.sceneRect().top() - 2) frontState.assignProperty(splash, "y", splash.y() - 100.0) scene.addItem(splash) self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) self.setMinimumSize(50, 50) self.setViewportUpdateMode(QGraphicsView.FullViewportUpdate) self.setCacheMode(QGraphicsView.CacheBackground) self.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform | QPainter.TextAntialiasing) if QGLFormat.hasOpenGL(): self.setViewport(QGLWidget(QGLFormat(QGL.SampleBuffers))) stateMachine.start()
class CurrentMusic(QFrame): """当前正在播放的音乐,包括一个图片,音乐名称,作曲人。以及鼠标移动到上面的遮罩。""" def __init__(self, parent=None): super(CurrentMusic, self).__init__() self.parent = parent self.grandparent = self.parent.parent self.setParent(self.grandparent) self.setObjectName("currentMusic") with open('QSS/currentMusic.qss', 'r') as f: self.setStyleSheet(f.read()) # 用于标记是否切换了歌曲,防止多次获取同一个歌词。 self.currentMusicId = 0 # 用于切换歌词,知道当前的歌词滚到哪一个了。 self.order = -2 # 用于切换歌词时滚动滚动条。 # self.sliderValue = 0 # 每一条歌词该滚多少。 # self.slideValue = 0 # 有多少条歌词控件。 self.count = 0 # 歌词缓存。 self.lyricCache = '' # 将窗口提前并激活窗口。 self.raise_() self.activateWindow() self.shortInfo = CurrentMusicShort(self) self.detailInfo = CurrentMusicDetail(self) # self.showDetail = 'animation' self.showShort = 'animation' self.mousePos = None self.mainLayout = QHBoxLayout(self) self.mainLayout.addWidget(self.shortInfo) self.mainLayout.addWidget(self.detailInfo) # 保证没有间隙。 self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.setSpacing(0) self.setFeatures() # 功能。 @checkOneFolder(cacheFolder) def setShortInfo(self, name=None, author=None, pic=None): """方便设置信息。""" if pic: cacheList = os.listdir(cacheFolder) names = str(pic[pic.rfind('/')+1:]) if names in cacheList: pic = cacheFolder+'/'+names self.shortInfo.musicPic.setSrc(pic) self.shortInfo.musicName.setText(name) self.shortInfo.musicAuthor.setText(author) def setDetailInfo(self): title = self.shortInfo.musicName.text() picSrc = self.shortInfo.musicPic.getSrc() blurSrc = blur(picSrc) self.detailInfo.titleLabel.setText(title) if blurSrc: self.detailInfo.lyricFrames.setStyleSheet(''' QScrollArea#lyricScroll {{ background-image: url({0}); }} '''.format(blurSrc)) self.showLyric() def getDetailInfo(self): """点击后进行动画效果的: 显示某歌曲的详细信息。""" self.shortInfo.hide() self.detailInfo.show() self.showDetail = QPropertyAnimation(self, b"geometry") x = self.pos().x() y = self.pos().y() self.showDetail.setStartValue(QRect(x, y, self.width(), self.height())) # 获取顶层父窗口的长度。 self.showDetail.setEndValue(QRect(0, self.grandparent.header.height()+3, self.grandparent.width(), self.grandparent.mainContent.height())) self.showDetail.setDuration(300) self.showDetail.setEasingCurve(QEasingCurve.InBack) self.showDetail.start(QAbstractAnimation.DeleteWhenStopped) # 将该组件显示在最前,默认会嵌入到父组件里面。 self.raise_() self.setDetailInfo() def showLyric(self): lyric = self.getLyric() # lyric.add_done_callback(lambda future: self.detailInfo.detailText.setText(centerHTML(future.result)())) lyric.add_done_callback(self.lyricCallback) def lyricCallback(self, future): """lyric加载完成后的回调函数。""" # [00:00.00] 作曲 : cyr # [00:01.00] 作词 : buzz # [00:17.460] # [00:33.630] :) self.detailInfo.removeAllLyricLabels() # 初始化。 self.count = 0 self.order = -2 result = future.result().split('\n') signal = self.parent.player.timeChanged for x, i in enumerate(result): data = re.findall(r'\[+(.*?)\]+(.*)', i) # [''] or [':)'] if not data: if not i: continue else: self.detailInfo.addLyricLabel(_LyricLabel('00:00', i, x, signal, self)) continue # [00:17.460] if not data[0][1]: self.detailInfo.addLyricLabel(_LyricLabel(data[0][0], '\n', x, signal, self)) continue # [00:01.00] 作词 : buzz self.detailInfo.addLyricLabel(_LyricLabel(data[0][0], data[0][1], x, signal, self)) self.count = x # 这边并不会返回添加了控件后的Value值。 # self.sliderValue = self.detailInfo.maximumValue() # self.slideValue = round(self.sliderValue/x) def slide(self): # 待优化。 # 问题如上所说。 # value = self.detailInfo.verticalScrollBar().value() maxValue = round(self.detailInfo.lyricFrames.maximumValue()/self.count)*self.order # for i in range(value, maxValue): self.detailInfo.lyricFrames.verticalScrollBar().setValue(maxValue) def unLightLyric(self): if self.order < 0: return self.detailInfo.allLyrics[self.order].unLightMe() @toTask def getLyric(self): musicInfo = self.parent.player.getCurrentMusicInfo() if not musicInfo: return "✧请慢慢欣赏~" musicId = musicInfo.get('music_id') if self.currentMusicId == musicId: return self.lyricCache # return self.detailInfo.detailText.toPlainText() lyricUrl = musicInfo.get('lyric') # 默认网易云,网易云没有返回歌词地址,所以会是None. if not lyricUrl: future = aAsync(netease.lyric, musicId) data = yield from future else: if 'xiami' in lyricUrl: future = aAsync(xiami.lyric, lyricUrl) data = yield from future elif lyricUrl == 'qq': # TODO # get qq music lyric. return "✧请慢慢欣赏~" if not data: self.currentMusicId = musicId return "✧请慢慢欣赏~" # 这里暂时处理下不获取时间信息,只获取歌词信息。 # data = re.sub(r'\[.*?\]', '', data) self.currentMusicId = musicId self.lyricCache = data return data def getShortInfo(self): """返回到原来的缩略图信息。""" self.detailInfo.hide() self.showShort = QPropertyAnimation(self, b"geometry") x = self.pos().x() y = self.pos().y() self.showShort.setStartValue(QRect(0, self.grandparent.header.height(), self.grandparent.width(), self.grandparent.mainContent.height())) self.showShort.setEndValue(QRect(0, self.grandparent.height()-64-self.parent.height(), self.grandparent.navigation.width(), 64)) self.showShort.setDuration(300) self.showShort.setEasingCurve(QEasingCurve.InBack) self.showShort.start(QAbstractAnimation.DeleteWhenStopped) self.shortInfo.show() self.raise_() def setFeatures(self): self.detailInfo.recoveryButton.clicked.connect(self.getShortInfo) # 事件。 def mousePressEvent(self, event): self.mousePos = QCursor.pos() def mouseReleaseEvent(self, evnet): if QCursor.pos() != self.mousePos: return else: self.getDetailInfo()