def _default__geo_animator(self): """ Create the default property animator for the rubber band. """ p = QPropertyAnimation(self._band, 'geometry') p.setDuration(self.band_geo_duration) return p
class BaseDialog(QDialog): """ Base para popup dialog en la esquina superior derecha """ def __init__(self, weditor): super(BaseDialog, self).__init__(weditor) self._weditor = weditor self.line = None # Popup self.setWindowFlags(Qt.Popup) # Posición self.qpoint = weditor.rect().topRight() self.global_point = weditor.mapToGlobal(self.qpoint) # Animación self._animation = QPropertyAnimation(self, "geometry") self._animation.setDuration(150) self._animation.setEasingCurve(QEasingCurve.Linear) key_escape = QShortcut(QKeySequence(Qt.Key_Escape), self) self.connect(key_escape, SIGNAL("activated()"), self._close) def showEvent(self, event): super(BaseDialog, self).showEvent(event) x, y = self.geometry().x(), self.geometry().y() self._animation.setStartValue(QRect(x, 0, self.width(), self.height())) self._animation.setEndValue(QRect(x, y, self.width(), self.height())) self._animation.start() self.line.setFocus() def _close(self): x, y = self.geometry().x(), self.geometry().y() self._animation.setStartValue(QRect(x, y, self.width(), self.height())) self._animation.setEndValue(QRect(x, 0, self.width(), self.height())) self._animation.start() self.connect(self._animation, SIGNAL("finished()"), self.close)
def createAnimationFromToFor(widget, fromValue, toValue, duration, propName, curve=QEasingCurve.InOutCubic): anim = QPropertyAnimation(widget, propName) anim.setDuration(duration) anim.setStartValue(fromValue) anim.setEndValue(toValue) anim.setEasingCurve(curve) return anim
def createAnimationFromToFor(widget, fromValue, toValue, duration, propName, curve = QEasingCurve.InOutCubic): anim = QPropertyAnimation(widget, propName) anim.setDuration(duration) anim.setStartValue(fromValue) anim.setEndValue(toValue) anim.setEasingCurve(curve) return anim
def anim_right(self): animation = QPropertyAnimation(self.label_icon, "geometry") animation.setDuration(250) animation.setStartValue(QRect(20, 0, 20, 20)) animation.setEndValue(QRect(0, 0, 20, 20)) animation.start() self.animation = animation
class BaseDialog(QDialog): """ Base para popup dialog en la esquina superior derecha """ def __init__(self, weditor): super(BaseDialog, self).__init__(weditor) self._weditor = weditor self.line = None # Popup self.setWindowFlags(Qt.Popup) # Posición self.qpoint = weditor.rect().topRight() self.global_point = weditor.mapToGlobal(self.qpoint) # Animación self._animation = QPropertyAnimation(self, "geometry") self._animation.setDuration(150) self._animation.setEasingCurve(QEasingCurve.Linear) key_escape = QShortcut(QKeySequence(Qt.Key_Escape), self) self.connect(key_escape, SIGNAL("activated()"), self._close) def showEvent(self, event): super(BaseDialog, self).showEvent(event) x, y = self.geometry().x(), self.geometry().y() self._animation.setStartValue(QRect(x, 0, self.width(), self.height())) self._animation.setEndValue(QRect(x, y, self.width(), self.height())) self._animation.start() self.line.setFocus() def _close(self): x, y = self.geometry().x(), self.geometry().y() self._animation.setStartValue(QRect(x, y, self.width(), self.height())) self._animation.setEndValue(QRect(x, 0, self.width(), self.height())) self._animation.start() self.connect(self._animation, SIGNAL("finished()"), self.close)
def _default__vis_animator(self): """ Create the default property animator for the rubber band. """ p = QPropertyAnimation(self._band, 'windowOpacity') p.setDuration(self.band_vis_duration) p.finished.connect(self._on_vis_finished) return p
def slideInWidget(self, widget, direction=Automatic): if self.indexOf(widget) == -1 or widget is self.currentWidget(): return if self._active: return self._active = True prev_widget = self.currentWidget() next_widget = widget if direction == self.Automatic: if self.indexOf(prev_widget) < self.indexOf(next_widget): direction = self.BottomToTop if self.verticalMode else self.RightToLeft else: direction = self.TopToBottom if self.verticalMode else self.LeftToRight width = self.frameRect().width() height = self.frameRect().height() # the following is important, to ensure that the new widget has correct geometry information when sliding in the first time next_widget.setGeometry(0, 0, width, height) if direction in (self.TopToBottom, self.BottomToTop): offset = QPoint( 0, height if direction == self.TopToBottom else -height) elif direction in (self.LeftToRight, self.RightToLeft): offset = QPoint(width if direction == self.LeftToRight else -width, 0) # re-position the next widget outside of the display area prev_widget_position = prev_widget.pos() next_widget_position = next_widget.pos() next_widget.move(next_widget_position - offset) next_widget.show() next_widget.raise_() prev_widget_animation = QPropertyAnimation(prev_widget, "pos") prev_widget_animation.setDuration(self.animationDuration) prev_widget_animation.setEasingCurve( QEasingCurve(self.animationEasingCurve)) prev_widget_animation.setStartValue(prev_widget_position) prev_widget_animation.setEndValue(prev_widget_position + offset) next_widget_animation = QPropertyAnimation(next_widget, "pos") next_widget_animation.setDuration(self.animationDuration) next_widget_animation.setEasingCurve( QEasingCurve(self.animationEasingCurve)) next_widget_animation.setStartValue(next_widget_position - offset) next_widget_animation.setEndValue(next_widget_position) self._animation_group.clear() self._animation_group.addAnimation(prev_widget_animation) self._animation_group.addAnimation(next_widget_animation) self._animation_group.start()
def slideInWidget(self, widget, direction=Automatic): if self.indexOf(widget) == -1 or widget is self.currentWidget(): return if self._active: return self._active = True prev_widget = self.currentWidget() next_widget = widget if direction == self.Automatic: if self.indexOf(prev_widget) < self.indexOf(next_widget): direction = self.BottomToTop if self.verticalMode else self.RightToLeft else: direction = self.TopToBottom if self.verticalMode else self.LeftToRight width = self.frameRect().width() height = self.frameRect().height() # the following is important, to ensure that the new widget has correct geometry information when sliding in the first time next_widget.setGeometry(0, 0, width, height) if direction in (self.TopToBottom, self.BottomToTop): offset = QPoint(0, height if direction == self.TopToBottom else -height) elif direction in (self.LeftToRight, self.RightToLeft): offset = QPoint(width if direction == self.LeftToRight else -width, 0) # re-position the next widget outside of the display area prev_widget_position = prev_widget.pos() next_widget_position = next_widget.pos() next_widget.move(next_widget_position - offset) next_widget.show() next_widget.raise_() prev_widget_animation = QPropertyAnimation(prev_widget, "pos") prev_widget_animation.setDuration(self.animationDuration) prev_widget_animation.setEasingCurve(QEasingCurve(self.animationEasingCurve)) prev_widget_animation.setStartValue(prev_widget_position) prev_widget_animation.setEndValue(prev_widget_position + offset) next_widget_animation = QPropertyAnimation(next_widget, "pos") next_widget_animation.setDuration(self.animationDuration) next_widget_animation.setEasingCurve(QEasingCurve(self.animationEasingCurve)) next_widget_animation.setStartValue(next_widget_position - offset) next_widget_animation.setEndValue(next_widget_position) self._animation_group.clear() self._animation_group.addAnimation(prev_widget_animation) self._animation_group.addAnimation(next_widget_animation) self._animation_group.start()
class CurrentSelection(QgsRubberBand): """ Position marker for the current location in the viewer. """ class AniObject(QObject): def __init__(self, band): super(CurrentSelection.AniObject, self).__init__() self.color = QColor() @pyqtProperty(int) def alpha(self): return self.color.alpha() @alpha.setter def alpha(self, value): self.color.setAlpha(value) def __init__(self, canvas): super(CurrentSelection, self).__init__(canvas) self.outline = QgsRubberBand(canvas) self.outline.setBrushStyle(Qt.NoBrush) self.outline.setWidth(5) self.outline.setIconSize(30) self.aniobject = CurrentSelection.AniObject(self) self.anim = QPropertyAnimation(self.aniobject, "alpha") self.anim.setDuration(500) self.anim.setStartValue(50) self.anim.setEndValue(100) self.anim.valueChanged.connect(self.value_changed) def setOutlineColour(self, color): self.outline.setColor(color) def setToGeometry(self, geom, layer): super(CurrentSelection, self).setToGeometry(geom, layer) self.outline.setToGeometry(geom, layer) self.anim.stop() self.anim.start() def reset(self, geomtype=QGis.Line): super(CurrentSelection, self).reset(geomtype) self.outline.reset(geomtype) self.anim.stop() def value_changed(self, value): self.setColor(self.aniobject.color) self.update() def setColor(self, color): self.aniobject.color = color super(CurrentSelection, self).setColor(color)
class CurrentSelection(QgsRubberBand): """ Position marker for the current location in the viewer. """ class AniObject(QObject): def __init__(self, band): super(CurrentSelection.AniObject, self).__init__() self.color = QColor() @pyqtProperty(int) def alpha(self): return self.color.alpha() @alpha.setter def alpha(self, value): self.color.setAlpha(value) def __init__(self, canvas): super(CurrentSelection, self).__init__(canvas) self.outline = QgsRubberBand(canvas) self.outline.setBrushStyle(Qt.NoBrush) self.outline.setWidth(5) self.outline.setIconSize(30) self.aniobject = CurrentSelection.AniObject(self) self.anim = QPropertyAnimation(self.aniobject, "alpha") self.anim.setDuration(500) self.anim.setStartValue(50) self.anim.setEndValue(100) self.anim.valueChanged.connect(self.value_changed) def setOutlineColour(self, color): self.outline.setColor(color) def setToGeometry(self, geom, layer): super(CurrentSelection, self).setToGeometry(geom, layer) self.outline.setToGeometry(geom, layer) self.anim.stop() self.anim.start() def reset(self, geomtype=QGis.Line): super(CurrentSelection, self).reset(geomtype) self.outline.reset(geomtype) self.anim.stop() def value_changed(self, value): self.setColor(self.aniobject.color) self.update() def setColor(self, color): self.aniobject.color = color super(CurrentSelection, self).setColor(color)
class Toast(QFrame): def __init__(self, text, info, parent=None): super(Toast, self).__init__(parent) self.info = info toast_lbl = QPushButton(text) toast_lbl.setFixedSize(200, 100) layout = QVBoxLayout() layout.addWidget(toast_lbl) self.setLayout(layout) self.set_ui() def set_ui(self): color = "#C09853" background_color = "#FCF8E3" border_color = "#FBEED5" if self.info == "error": color = "#B94A48" background_color = "#F2DEDE" border_color = "#EED3D7" elif self.info == "success": color = "#468847" background_color = "#DFF0D8" border_color = "#D6E9C6" elif self.info == "info": color = "#3A87AD" background_color = "#D9EDF7" border_color = "#BCE8F1" self.setStyleSheet(""" QPushButton{ color: %s; background-color: %s; border: 1px solid %s; font: 14px; border-radius: 4px; } """ % (color, background_color, border_color)) def animation_geometry(self, widget, init=(35, 250, 250, 200), end=(35, 250, 250, 200), finish=None, duration=2000): init_rect = QRect(init[0], init[1], init[2], init[3]) end_rect = QRect(end[0], end[1], end[2], end[3]) self.animation = QPropertyAnimation(widget, "geometry") self.animation.setStartValue(init_rect) self.animation.setEndValue(end_rect) self.animation.setDuration(duration) self.animation.start() if finish: self.connect(self.animation, SIGNAL('finished()'), finish) def show_toast(self, time_=3000): self.show() self.animation_geometry(self, finish=self.hide, duration=time_)
def trigger(self, ui): """ Trigger this animation """ damage_counter = DamageCounter(damage=str(self.damage), colour=self.colour, parent=ui) ui.view.scene().addItem(damage_counter) damage_counter.setZValue(zorder_counter) bounds = damage_counter.boundingRect() width = bounds.width() rand = Random() damage_counter.setPos((self.location[0] * 32 + 16 - (width / 2) + rand.randint(-16, 16)) + self.offset[0], self.location[1] * 32 + self.offset[1]) animation = QSequentialAnimationGroup() moving = QPropertyAnimation(damage_counter.adapter, 'y_location') moving.setDuration(750) moving.setStartValue(self.location[1] * 32 + self.offset[1]) moving.setEndValue(self.location[1] * 32 - 32 + self.offset[1]) curve = QEasingCurve(QEasingCurve.OutElastic) moving.setEasingCurve(curve) animation.addAnimation(moving) fading = QPropertyAnimation(damage_counter.adapter, 'opacity') fading.setDuration(750) fading.setStartValue(1.0) fading.setEndValue(0.0) animation.addAnimation(fading) def clean_up(): animation.stop() ui.animations.remove(animation) ui.view.items().remove(damage_counter) ui.remove_finished_animation() animation.finished.connect(clean_up) ui.animations.append(animation) animation.start()
def trigger(self, ui): """ Trigger this animation """ glyph = [ glyph for glyph in ui.scene.items() if hasattr(glyph, 'entity') and glyph.entity == self.mover ][0] if self.direction in (2, 3, 4): self.flipped = True self.offset = 32 if self.direction in (6, 7, 8): self.flipped = False self.offset = 0 if self.flipped: glyph.flipped = True glyph.setTransform(QTransform.fromScale(-1, 1)) else: glyph.flipped = False glyph.setTransform(QTransform.fromScale(1, 1)) if glyph.entity.artificial_intelligence: adapter = MapGlyphAdapter(ui, glyph) else: adapter = MapGlyphAdapter(ui, glyph, True) animation = QParallelAnimationGroup() move_y = QPropertyAnimation(adapter, 'y_location') move_y.setDuration(100) move_y.setStartValue(self.start[1] * 32) move_y.setEndValue(self.destination[1] * 32) move_x = QPropertyAnimation(adapter, 'x_location') move_x.setDuration(100) move_x.setStartValue(self.start[0] * 32 + self.offset) move_x.setEndValue(self.destination[0] * 32 + self.offset) animation.addAnimation(move_y) animation.addAnimation(move_x) ui.animations.append(animation) animation.finished.connect(ui.remove_finished_animation) animation.start()
def RestoreSize(self): ''' Restore Dialog Size ''' dw = self.s.value("EquirectangularViewer/width") dh = self.s.value("EquirectangularViewer/height") if dw is None: return size = self.size() anim = QPropertyAnimation(self, 'size', self) anim.setStartValue(size) anim.setEndValue(QSize(dw, dh)) anim.setDuration(1) anim.start() qApp.processEvents() return
class test(QDialog): def __init__(self,parent=None): super(test,self).__init__(parent) self.pushbutton = MyButton('Popup Button') # self.pushbutton.setAutoFillBackground(False) self.pushbutton.move(0, 50) # self._alpha = 255 # self.pushbutton.setStyle('plastique') # self.animation = QPropertyAnimation(self.pushbutton, "geometry") # self.animation.setDuration(1000) # self.animation.setKeyValueAt(0, QRect(100, 100, 50, 30)); # self.animation.setKeyValueAt(0.8, QRect(150, 150, 50, 30)); # self.animation.setKeyValueAt(1, QRect(100, 100, 50, 30)); self.animation = QPropertyAnimation(self.pushbutton, "alpha") self.animation.setDuration(1000) # self.animation.setStartValue(20) # self.animation.setEndValue(255) self.animation.setKeyValueAt(0, 10) self.animation.setKeyValueAt(0.5, 200) self.animation.setKeyValueAt(1, 255) self.animation.setLoopCount(5) self.animation.start() # print(self.pushbutton) layout = QVBoxLayout() layout.addWidget(self.pushbutton) # layout.addLayout(btnlayout2) # layout.addLayout(bottomlayout2) self.setLayout(layout) self.setGeometry(100, 100, 200, 200) # menu = QtGui.QMenu() # menu.addAction('This is Action 1', self.Action1) # menu.addAction('This is Action 2', self.Action2) # pushbutton.setMenu(menu) # self.setCentralWidget(pushbutton) def Action1(self): print('You selected Action 1') def Action2(self): print('You selected Action 2')
class HtmlViewerWidget(QWidget): def __init__(self, parent): super(HtmlViewerWidget, self).__init__(parent) self.setLayout(QGridLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.view = QWebView() self.view.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks) self.frame = QFrame() self.frame.setLayout(QGridLayout()) self.frame.layout().setContentsMargins(0, 0, 0, 0) self.toolbar = QToolBar() self.spacer = QWidget() self.spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.copyAction = self.toolbar.addAction(QIcon(":/icons/clipboard"), "Copy Text") self.label = QLabel() self.closeAction = self.toolbar.addAction(QIcon(":/icons/cancel"), "Close") self.spaceraction = self.toolbar.insertWidget(self.closeAction, self.spacer) self.labelaction = self.toolbar.insertWidget(self.spaceraction, self.label) self.closeAction.triggered.connect(self.close) self.copyAction.triggered.connect(self.copy_text) self.layout().addWidget(self.frame) self.frame.layout().addWidget(self.toolbar) self.frame.layout().addWidget(self.view) self.effect = QGraphicsOpacityEffect() self.label.setGraphicsEffect(self.effect) self.anim = QPropertyAnimation(self.effect, "opacity") self.anim.setDuration(2000) self.anim.setStartValue(1.0) self.anim.setEndValue(0.0) self.anim.setEasingCurve(QEasingCurve.OutQuad) def copy_text(self): self.label.setText("Copied to clipboard") text = self.view.page().mainFrame().toPlainText() QApplication.clipboard().setText(text) self.anim.stop() self.anim.start() def showHTML(self, template, level, **data): html = templates.render_tample(template, **data) self.view.setHtml(html, templates.baseurl)
def trigger(self, ui): """ Trigger this animation """ glyph = [glyph for glyph in ui.scene.items() if hasattr(glyph, 'entity') and glyph.entity == self.mover][0] if self.direction in (2, 3, 4): self.flipped = True self.offset = 32 if self.direction in (6, 7, 8): self.flipped = False self.offset = 0 if self.flipped: glyph.flipped = True glyph.setTransform(QTransform.fromScale(-1, 1)) else: glyph.flipped = False glyph.setTransform(QTransform.fromScale(1, 1)) if glyph.entity.artificial_intelligence: adapter = MapGlyphAdapter(ui, glyph) else: adapter = MapGlyphAdapter(ui, glyph, True) animation = QParallelAnimationGroup() move_y = QPropertyAnimation(adapter, 'y_location') move_y.setDuration(100) move_y.setStartValue(self.start[1] * 32) move_y.setEndValue(self.destination[1] * 32) move_x = QPropertyAnimation(adapter, 'x_location') move_x.setDuration(100) move_x.setStartValue(self.start[0] * 32 + self.offset) move_x.setEndValue(self.destination[0] * 32 + self.offset) animation.addAnimation(move_y) animation.addAnimation(move_x) ui.animations.append(animation) animation.finished.connect(ui.remove_finished_animation) animation.start()
def test(): # 动来动去的按钮 button = QPushButton("Button") button.show() # 生成一个动画, 它会修改button的geometry属性 animation = QPropertyAnimation(button, "geometry") # 动画时间是10秒 animation.setDuration(10000) # 开始的位置 animation.setStartValue(QRect(0, 0, 100, 30)) # 结束的位置 animation.setEndValue(QRect(250, 250, 100, 30)) # 开始吧 animation.start() app.exec_()
def groupAnimation(ws, btngroup): # 建立一个平行的动作组 ag = QParallelAnimationGroup() for w in ws: tmpbtn = btngroup.button(int(w[0])) # 对于每个按钮, 都生成一个进入的动作 a = QPropertyAnimation(tmpbtn, "alpha") a.setDuration(200) a.setKeyValueAt(0, 10) # a.setKeyValueAt(0.5, 200) a.setKeyValueAt(1, 255) a.setLoopCount(-1) a.setEasingCurve(QEasingCurve.OutQuad) # a.setStartValue(QRect(-100, w.y(), w.width(), w.height())) # a.setEndValue(w.geometry()) # 添加到组里面去 ag.addAnimation(a) return ag
class LineAnimation(Animation): def getPos(self): return self.__pos def setPos(self, pos): self.__pos = pos pos = pyqtProperty("QPointF", getPos, setPos) def __init__(self, p1, p2, color, duration, parent = None): super(LineAnimation, self).__init__(parent) self.startPoint = QPointF(p1[0], p1[1]) self.endPoint = QPointF(p2[0], p2[1]) self.__pos = self.startPoint self.color = color self.anim = QPropertyAnimation(self, "pos", self) self.anim.setStartValue(self.startPoint) self.anim.setEndValue(self.endPoint) self.anim.setDuration(duration) self.anim.valueChanged.connect(self.updated) self.anim.finished.connect(self.finished) def start(self): self.anim.start() def stop(self): self.anim.stop() def paint(self, painter): pen = QPen(Qt.black) pen.setWidthF(2.5) painter.setPen(pen) line = QLineF(self.startPoint, self.pos) painter.drawLine(line) if self.pos != self.startPoint: #draw arrowhead a = line.angle() l1 = QLineF.fromPolar(25, a - 155) l1.translate(self.pos) l2 = QLineF.fromPolar(25, a + 155) l2.translate(self.pos) painter.drawLine(l1) painter.drawLine(l2)
class HtmlViewerWidget(QWidget): def __init__(self, parent): super(HtmlViewerWidget, self).__init__(parent) self.setLayout(QGridLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.view = QWebView() self.view.page().setLinkDelegationPolicy(QWebPage.DelegateAllLinks) self.frame = QFrame() self.frame.setLayout(QGridLayout()) self.frame.layout().setContentsMargins(0, 0, 0, 0) self.toolbar = QToolBar() self.spacer = QWidget() self.spacer.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) self.copyAction = self.toolbar.addAction(QIcon(":/icons/clipboard"), "Copy Text") self.label = QLabel() self.closeAction = self.toolbar.addAction(QIcon(":/icons/cancel"), "Close") self.spaceraction = self.toolbar.insertWidget(self.closeAction, self.spacer) self.labelaction = self.toolbar.insertWidget(self.spaceraction, self.label) self.closeAction.triggered.connect(self.close) self.copyAction.triggered.connect(self.copy_text) self.layout().addWidget(self.frame) self.frame.layout().addWidget(self.toolbar) self.frame.layout().addWidget(self.view) self.effect = QGraphicsOpacityEffect() self.label.setGraphicsEffect(self.effect) self.anim = QPropertyAnimation(self.effect, "opacity") self.anim.setDuration(2000) self.anim.setStartValue(1.0) self.anim.setEndValue(0.0) self.anim.setEasingCurve(QEasingCurve.OutQuad ) def copy_text(self): self.label.setText("Copied to clipboard") text = self.view.page().mainFrame().toPlainText() QApplication.clipboard().setText(text) self.anim.stop() self.anim.start() def showHTML(self, template, level, **data): html = templates.render_tample(template, **data) self.view.setHtml(html, templates.baseurl)
def ResizeDialog(self): ''' Expanded/Decreased Dialog ''' sender = QObject.sender(self) w = self.width() h = self.height() size = self.size() anim = QPropertyAnimation(self, 'size', self) anim.setStartValue(size) if sender.objectName() == "btn_ZoomOut": anim.setEndValue(QSize(w - 50, h - 50)) else: anim.setEndValue(QSize(w + 50, h + 50)) anim.setDuration(300) anim.start() qApp.processEvents() return
def _start_animation(self, show=True): if not self.USE_ANIMATIONS: g = self.child.geometry() self.child_state = self.STATE_ANIMATING if show: g.setHeight(self.preferred_size.height()) else: g.setHeight(0) self.child.setGeometry(g) self.mandated_size.setHeight(g.height()) self.update() self.child_state = self.STATE_VISIBLE if show else self.STATE_HIDDEN return self.update() a = QPropertyAnimation(self.child, "geometry", self) g = self.child.geometry() g.setHeight(0) a.setStartValue(g) g.setHeight(self.preferred_size.height()) a.setEndValue(g) a.setEasingCurve(QEasingCurve.OutQuad) a.setDuration(self.duration) def valueChanged(qv): r = qv.toRect() self.mandated_size.setHeight(r.height()) self.update() connect(a, SIGNAL("valueChanged(QVariant)"), valueChanged) if not show: a.setDirection(a.Backward) connect(a, SIGNAL("finished()"), lambda: setattr(self, "child_state", self.STATE_HIDDEN)) else: a.setDirection(a.Forward) connect(a, SIGNAL("finished()"), lambda: setattr(self, "child_state", self.STATE_VISIBLE)) self.child_state = self.STATE_ANIMATING a.start(a.DeleteWhenStopped)
class OutputTab(QTabWidget): def __init__(self,parent): QTabWidget.__init__(self,parent) self.setTabBar(MyTabBar(self)) self.setMaximumHeight(200)#260 self.anim = QPropertyAnimation(self, "geometry") self.anim.setDuration(3000) self.anim.setStartValue(QRect(0,0,100,0)) self.anim.setEndValue(QRect(0,0,100,200)) self.anim.setEasingCurve(QEasingCurve.InOutQuad) if(config.hide() == 1): #self.setFixedHeight(200) self.timer = QTimer(self) self.timer.timeout.connect(self.close) #self.connect(self.tabBar(), SIGNAL("tabno"),self.pop_out) #self.connect(self.tabBar(), SIGNAL("enter"),self.enter_show) #self.connect(self.tabBar(), SIGNAL("leave"),self.leave_hide) self.hide() else: #self.setFixedHeight(200) self.hide() def pop_out(self,no): #print "Hover Over Output tab: ",no if(no != 2): self.setCurrentIndex(no) def enter_show(self): self.anim.start() self.show() def leave_hide(self): self.timer.start(2000) def close(self): #self.setFixedHeight(30) self.timer.stop()
class Slider(QFrame): def __init__(self, minimap): QFrame.__init__(self, minimap) self._minimap = minimap self.setStyleSheet("background: gray; border-radius: 3px;") # Opacity self.effect = QGraphicsOpacityEffect() self.setGraphicsEffect(self.effect) self.effect.setOpacity(0.2) # Animación self.animation = QPropertyAnimation(self.effect, "opacity") self.animation.setDuration(150) # Cursor self.setCursor(Qt.OpenHandCursor) def mouseMoveEvent(self, event): super(Slider, self).mouseMoveEvent(event) #FIXME: funciona algo loco pos = self.mapToParent(event.pos()) dy = pos.y() - (self.height() / 2) if dy < 0: dy = 0 self.move(0, dy) pos.setY(pos.y() - event.pos().y()) self._minimap._weditor.verticalScrollBar().setValue(pos.y()) self._minimap.verticalScrollBar().setSliderPosition( self._minimap.verticalScrollBar().sliderPosition() + 2) self._minimap.verticalScrollBar().setValue(pos.y() - event.pos().y()) def mousePressEvent(self, event): super(Slider, self).mousePressEvent(event) self.setCursor(Qt.ClosedHandCursor) def mouseReleaseEvent(self, event): super(Slider, self).mouseReleaseEvent(event) self.setCursor(Qt.OpenHandCursor)
class ExplodingAnimation(Animation): def __init__(self, center, duration, parent = None): super(ExplodingAnimation, self).__init__(parent) self.center = center self.__radius = 1.0 self.anim = QPropertyAnimation(self, "radius") self.anim.setStartValue(1.0) self.anim.setEndValue(100.0) self.anim.setDuration(duration) self.anim.setEasingCurve(QEasingCurve.OutExpo) self.anim.valueChanged.connect(self.updated) self.anim.finished.connect(self.finished) def start(self): self.anim.start() def stop(self): self.anim.stop() def getRadius(self): return self.__radius def setRadius(self, r): self.__radius = r radius = pyqtProperty("qreal", getRadius, setRadius) def paint(self, painter): opacity = 1.0 - float(self.anim.currentTime()) / self.anim.duration() pen = QPen(QColor(255, 0, 0, opacity * 255)) pen.setWidth(3) painter.setPen(pen) painter.setBrush(Qt.transparent) rect = QRect(0, 0, self.radius * 2, self.radius * 2) rect.moveCenter(self.center) painter.drawEllipse(rect)
class Slider(QFrame): def __init__(self, minimap): QFrame.__init__(self, minimap) self._minimap = minimap self.setStyleSheet("background: gray; border-radius: 3px;") # Opacity self.effect = QGraphicsOpacityEffect() self.setGraphicsEffect(self.effect) self.effect.setOpacity(0.2) # Animación self.animation = QPropertyAnimation(self.effect, "opacity") self.animation.setDuration(150) # Cursor self.setCursor(Qt.OpenHandCursor) def mouseMoveEvent(self, event): super(Slider, self).mouseMoveEvent(event) #FIXME: funciona algo loco pos = self.mapToParent(event.pos()) dy = pos.y() - (self.height() / 2) if dy < 0: dy = 0 self.move(0, dy) pos.setY(pos.y() - event.pos().y()) self._minimap._weditor.verticalScrollBar().setValue(pos.y()) self._minimap.verticalScrollBar().setSliderPosition( self._minimap.verticalScrollBar().sliderPosition() + 2) self._minimap.verticalScrollBar().setValue(pos.y() - event.pos().y()) def mousePressEvent(self, event): super(Slider, self).mousePressEvent(event) self.setCursor(Qt.ClosedHandCursor) def mouseReleaseEvent(self, event): super(Slider, self).mouseReleaseEvent(event) self.setCursor(Qt.OpenHandCursor)
class NodeBodyItem(GraphicsPathObject): """ The central part (body) of the `NodeItem`. """ def __init__(self, parent=None): GraphicsPathObject.__init__(self, parent) assert(isinstance(parent, NodeItem)) self.__processingState = 0 self.__progress = -1 self.__animationEnabled = False self.__isSelected = False self.__hasFocus = False self.__hover = False self.__shapeRect = QRectF(-10, -10, 20, 20) self.setAcceptHoverEvents(True) self.setFlag(QGraphicsItem.ItemSendsScenePositionChanges, True) self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True) self.setPen(QPen(Qt.NoPen)) self.setPalette(default_palette()) self.shadow = QGraphicsDropShadowEffect( blurRadius=3, color=QColor(SHADOW_COLOR), offset=QPointF(0, 0), ) self.setGraphicsEffect(self.shadow) self.shadow.setEnabled(True) self.__blurAnimation = QPropertyAnimation(self.shadow, "blurRadius", self) self.__blurAnimation.setDuration(100) self.__blurAnimation.finished.connect(self.__on_finished) self.__pingAnimation = QPropertyAnimation(self, "scale", self) self.__pingAnimation.setDuration(250) self.__pingAnimation.setKeyValues([(0.0, 1.0), (0.5, 1.1), (1.0, 1.0)]) # TODO: The body item should allow the setting of arbitrary painter # paths (for instance rounded rect, ...) def setShapeRect(self, rect): """ Set the item's shape `rect`. The item should be confined within this rect. """ path = QPainterPath() path.addEllipse(rect) self.setPath(path) self.__shapeRect = rect def setPalette(self, palette): """ Set the body color palette (:class:`QPalette`). """ self.palette = palette self.__updateBrush() def setAnimationEnabled(self, enabled): """ Set the node animation enabled. """ if self.__animationEnabled != enabled: self.__animationEnabled = enabled def setProcessingState(self, state): """ Set the processing state of the node. """ if self.__processingState != state: self.__processingState = state if not state and self.__animationEnabled: self.ping() def setProgress(self, progress): """ Set the progress indicator state of the node. `progress` should be a number between 0 and 100. """ self.__progress = progress self.update() def ping(self): """ Trigger a 'ping' animation. """ animation_restart(self.__pingAnimation) def hoverEnterEvent(self, event): self.__hover = True self.__updateShadowState() return GraphicsPathObject.hoverEnterEvent(self, event) def hoverLeaveEvent(self, event): self.__hover = False self.__updateShadowState() return GraphicsPathObject.hoverLeaveEvent(self, event) def paint(self, painter, option, widget): """ Paint the shape and a progress meter. """ # Let the default implementation draw the shape if option.state & QStyle.State_Selected: # Prevent the default bounding rect selection indicator. option.state = option.state ^ QStyle.State_Selected GraphicsPathObject.paint(self, painter, option, widget) if self.__progress >= 0: # Draw the progress meter over the shape. # Set the clip to shape so the meter does not overflow the shape. painter.setClipPath(self.shape(), Qt.ReplaceClip) color = self.palette.color(QPalette.ButtonText) pen = QPen(color, 5) painter.save() painter.setPen(pen) painter.setRenderHints(QPainter.Antialiasing) span = int(self.__progress * 57.60) painter.drawArc(self.__shapeRect, 90 * 16, -span) painter.restore() def __updateShadowState(self): if self.__hasFocus: color = QColor(FOCUS_OUTLINE_COLOR) self.setPen(QPen(color, 1.5)) else: self.setPen(QPen(Qt.NoPen)) radius = 3 enabled = False if self.__isSelected: enabled = True radius = 7 if self.__hover: radius = 17 enabled = True if enabled and not self.shadow.isEnabled(): self.shadow.setEnabled(enabled) if self.__animationEnabled: if self.__blurAnimation.state() == QPropertyAnimation.Running: self.__blurAnimation.pause() self.__blurAnimation.setStartValue(self.shadow.blurRadius()) self.__blurAnimation.setEndValue(radius) self.__blurAnimation.start() else: self.shadow.setBlurRadius(radius) def __updateBrush(self): palette = self.palette if self.__isSelected: cg = QPalette.Active else: cg = QPalette.Inactive palette.setCurrentColorGroup(cg) c1 = palette.color(QPalette.Light) c2 = palette.color(QPalette.Button) grad = radial_gradient(c2, c1) self.setBrush(QBrush(grad)) # TODO: The selected and focus states should be set using the # QStyle flags (State_Selected. State_HasFocus) def setSelected(self, selected): """ Set the `selected` state. .. note:: The item does not have `QGraphicsItem.ItemIsSelectable` flag. This property is instead controlled by the parent NodeItem. """ self.__isSelected = selected self.__updateBrush() def setHasFocus(self, focus): """ Set the `has focus` state. .. note:: The item does not have `QGraphicsItem.ItemIsFocusable` flag. This property is instead controlled by the parent NodeItem. """ self.__hasFocus = focus self.__updateShadowState() def __on_finished(self): if self.shadow.blurRadius() == 0: self.shadow.setEnabled(False)
class NodeBodyItem(GraphicsPathObject): """ The central part (body) of the `NodeItem`. """ def __init__(self, parent=None): GraphicsPathObject.__init__(self, parent) assert (isinstance(parent, NodeItem)) self.__processingState = 0 self.__progress = -1 self.__animationEnabled = False self.__isSelected = False self.__hasFocus = False self.__hover = False self.__shapeRect = QRectF(-10, -10, 20, 20) self.setAcceptHoverEvents(True) self.setFlag(QGraphicsItem.ItemSendsScenePositionChanges, True) self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True) self.setPen(QPen(Qt.NoPen)) self.setPalette(default_palette()) self.shadow = QGraphicsDropShadowEffect( blurRadius=3, color=QColor(SHADOW_COLOR), offset=QPointF(0, 0), ) self.setGraphicsEffect(self.shadow) self.shadow.setEnabled(True) self.__blurAnimation = QPropertyAnimation(self.shadow, "blurRadius", self) self.__blurAnimation.setDuration(100) self.__blurAnimation.finished.connect(self.__on_finished) self.__pingAnimation = QPropertyAnimation(self, "scale", self) self.__pingAnimation.setDuration(250) self.__pingAnimation.setKeyValues([(0.0, 1.0), (0.5, 1.1), (1.0, 1.0)]) # TODO: The body item should allow the setting of arbitrary painter # paths (for instance rounded rect, ...) def setShapeRect(self, rect): """ Set the item's shape `rect`. The item should be confined within this rect. """ path = QPainterPath() path.addEllipse(rect) self.setPath(path) self.__shapeRect = rect def setPalette(self, palette): """ Set the body color palette (:class:`QPalette`). """ self.palette = palette self.__updateBrush() def setAnimationEnabled(self, enabled): """ Set the node animation enabled. """ if self.__animationEnabled != enabled: self.__animationEnabled = enabled def setProcessingState(self, state): """ Set the processing state of the node. """ if self.__processingState != state: self.__processingState = state if not state and self.__animationEnabled: self.ping() def setProgress(self, progress): """ Set the progress indicator state of the node. `progress` should be a number between 0 and 100. """ self.__progress = progress self.update() def ping(self): """ Trigger a 'ping' animation. """ animation_restart(self.__pingAnimation) def hoverEnterEvent(self, event): self.__hover = True self.__updateShadowState() return GraphicsPathObject.hoverEnterEvent(self, event) def hoverLeaveEvent(self, event): self.__hover = False self.__updateShadowState() return GraphicsPathObject.hoverLeaveEvent(self, event) def paint(self, painter, option, widget): """ Paint the shape and a progress meter. """ # Let the default implementation draw the shape if option.state & QStyle.State_Selected: # Prevent the default bounding rect selection indicator. option.state = option.state ^ QStyle.State_Selected GraphicsPathObject.paint(self, painter, option, widget) if self.__progress >= 0: # Draw the progress meter over the shape. # Set the clip to shape so the meter does not overflow the shape. painter.setClipPath(self.shape(), Qt.ReplaceClip) color = self.palette.color(QPalette.ButtonText) pen = QPen(color, 5) painter.save() painter.setPen(pen) painter.setRenderHints(QPainter.Antialiasing) span = max(1, int(self.__progress * 57.60)) painter.drawArc(self.__shapeRect, 90 * 16, -span) painter.restore() def __updateShadowState(self): if self.__hasFocus: color = QColor(FOCUS_OUTLINE_COLOR) self.setPen(QPen(color, 1.5)) else: self.setPen(QPen(Qt.NoPen)) radius = 3 enabled = False if self.__isSelected: enabled = True radius = 7 if self.__hover: radius = 17 enabled = True if enabled and not self.shadow.isEnabled(): self.shadow.setEnabled(enabled) if self.__animationEnabled: if self.__blurAnimation.state() == QPropertyAnimation.Running: self.__blurAnimation.pause() self.__blurAnimation.setStartValue(self.shadow.blurRadius()) self.__blurAnimation.setEndValue(radius) self.__blurAnimation.start() else: self.shadow.setBlurRadius(radius) def __updateBrush(self): palette = self.palette if self.__isSelected: cg = QPalette.Active else: cg = QPalette.Inactive palette.setCurrentColorGroup(cg) c1 = palette.color(QPalette.Light) c2 = palette.color(QPalette.Button) grad = radial_gradient(c2, c1) self.setBrush(QBrush(grad)) # TODO: The selected and focus states should be set using the # QStyle flags (State_Selected. State_HasFocus) def setSelected(self, selected): """ Set the `selected` state. .. note:: The item does not have `QGraphicsItem.ItemIsSelectable` flag. This property is instead controlled by the parent NodeItem. """ self.__isSelected = selected self.__updateBrush() def setHasFocus(self, focus): """ Set the `has focus` state. .. note:: The item does not have `QGraphicsItem.ItemIsFocusable` flag. This property is instead controlled by the parent NodeItem. """ self.__hasFocus = focus self.__updateShadowState() def __on_finished(self): if self.shadow.blurRadius() == 0: self.shadow.setEnabled(False)
class CImprovedPanel(QFrame): def __init__(self, parent=None): QFrame.__init__(self, parent) #FADING self.__opacity_effect = QGraphicsOpacityEffect() self.__fading_timer = QTimer(parent) self.__fading_timer.timeout.connect(self.__on_fading_timer) self.__FADE_TYPE = Enum("IN", "OUT") self.__fade_time = 20 self.__opacity = 1.0 self.__opacity_fading_coefficient = 0.02 self.__selected_fade_type = self.__FADE_TYPE.IN self.resizeEvent = self.__onResize #MOVE self.__move_animation_type = QEasingCurve.Linear self.__move_time = 350 self.__is_moving = False #RESIZE self.__resize_animation_type = QEasingCurve.Linear self.__resize_time = 700 self.__is_resizing = False #PIXMAP & MASCHERA self.__pmap = QPixmap(self.size()) self.__pmap_fname = "" self.__show_mask_preview = False #SHADOW self.__shadow_Xoffset = 3.0 #default value self.__shadow_Yoffset = 3.0 #default value self.__shadow_blur_radius = 8.0 #default value self.__shadow_color = QColor(38,38,38,150) #default value self.__shadow_effect = QGraphicsDropShadowEffect() self.__shadow_effect.setXOffset(self.__shadow_Xoffset) self.__shadow_effect.setYOffset(self.__shadow_Yoffset) self.__shadow_effect.setBlurRadius(self.__shadow_blur_radius) self.__shadow_effect.setColor(self.__shadow_color) self._shadow_visible = False ##FUNZIONI PER FADING def fadeIn(self): """ Labels fades in from completely invisible to completely visible. """ self.__opacity = 0.0 self.__selected_fade_type = self.__FADE_TYPE.IN self.__fading_timer.start(self.__fade_time) def fadeOut(self): """ Labels fades out from completely visible to completely invisible. """ self.__selected_fade_type = self.__FADE_TYPE.OUT self.__fading_timer.start(self.__fade_time) def setFadeTime(self, value): """ Sets fading time. Everytime interval is reached, alpha is increased (or decreased) by __opacity_fading_coefficient. @param value: fade time (msec) @type value: int """ self.__fade_time = value def getFadeTime(self): return self.__fade_time fadeInterval = QtCore.pyqtProperty("int", getFadeTime, setFadeTime) def setFadeCoefficient(self, value): """ Sets fading coefficient. Alpha is increased (or decreased) by this value. @param value: coefficient (min 0.0 - max 1.0) @type value: float """ self.__opacity_fading_coefficient = value def getFadeCoefficient(self): return self.__opacity_fading_coefficient fadeCoefficient = QtCore.pyqtProperty("double", getFadeCoefficient, setFadeCoefficient) def __on_fading_timer(self): if self.__selected_fade_type == self.__FADE_TYPE.OUT: if self.__opacity > 0: self.__opacity -= self.__opacity_fading_coefficient self.__opacity_effect.setOpacity(self.__opacity) self.setGraphicsEffect(self.__opacity_effect) else: self.__fading_timer.stop() if self.__selected_fade_type == self.__FADE_TYPE.IN: if self.__opacity <= 1.0: self.__opacity += self.__opacity_fading_coefficient self.__opacity_effect.setOpacity(self.__opacity) self.setGraphicsEffect(self.__opacity_effect) else: self.__fading_timer.stop() ## FUNZIONI PER SPOSTAMENTO VERSO PUNTO (ANIMATO) def setMoveAnimationType(self, animation_type): """ Sets move animation type. @param animation_type: animation type @type animation_type: QtEasingCurve """ self.__move_animation_type = animation_type def getMoveAnimationType(self): return self.__move_animation_type #asd = QtCore.pyqtProperty("QEasingCurve", getMoveAnimationType, setMoveAnimationType) #sembra nn essere supportato per ora (06/05/2013) def setMoveTime(self, value): """ Sets animation moving time. @param value: animation time (duration) (msec) @type value: int """ self.__move_time = value def getMoveTime(self): return self.__move_time moveTime = QtCore.pyqtProperty("int", getMoveTime, setMoveTime) def setResizeTime(self, value): """ Sets animation resize time. @param value: animation time (duration) (msec) @type value: int """ self.__resize_time = value def getResizeTime(self): return self.__resize_time resizeTime = QtCore.pyqtProperty("int", getResizeTime, setResizeTime) def moveTo(self, x, y): """ Move itself to a given point with the given animation in the given duration. @param x: X point coordinate @type x: int @param y: Y point coordinate @type y: int """ if self.__is_moving: return self.__is_moving = True self.__starting_position = QPoint(self.pos()) self.__moveAnimation = QPropertyAnimation(self, "pos", self) self.__moveAnimation.finished.connect(self.__on_finished_moving) self.__moveAnimation.setDuration(self.__move_time) self.__moveAnimation.setEasingCurve(self.__move_animation_type) self.__moveAnimation.setStartValue(self.__starting_position) self.__moveAnimation.setEndValue(QPoint(x, y)) self.__moveAnimation.start() def hideLeft(self): """ Panel hides sliding on the left. The slide amount is equal to his width - 5px. """ dest_x = self.geometry().x() - self.width() - 5 dest_y = self.geometry().y() self.moveTo(dest_x, dest_y) def showFromLeft(self): """ Panel shows sliding from the left. The slide amount is equal to his width + 5px. """ dest_x = self.geometry().x() + self.width() + 5 dest_y = self.geometry().y() self.moveTo(dest_x, dest_y) def hideRight(self): """ Panel hides sliding on the right. The slide amount is equal to his width - 5px. """ dest_x = self.geometry().x() + self.width() + 5 dest_y = self.geometry().y() self.moveTo(dest_x, dest_y) def showFromRight(self): """ Panel shows sliding from the right. The slide amount is equal to his width + 5px. """ dest_x = self.geometry().x() - self.width() - 5 dest_y = self.geometry().y() self.moveTo(dest_x, dest_y) def hideTop(self): """ Panel hides sliding on the top. The slide amount is equal to his height - 5px. """ dest_x = self.geometry().x() dest_y = self.geometry().y() - self.height() - 5 self.moveTo(dest_x, dest_y) def showFromTop(self): """ Panel shows sliding from the top. The slide amount is equal to his height - 5px. """ dest_x = self.geometry().x() dest_y = self.geometry().y() + self.height() - 5 self.moveTo(dest_x, dest_y) def hideBottom(self): """ Panel hides sliding to the bottom. The slide amount is equal to his height - 5px. """ dest_x = self.geometry().x() dest_y = self.geometry().y() + self.height() + 5 self.moveTo(dest_x, dest_y) def showFromBottom(self): """ Panel hides sliding from the bottom. The slide amount is equal to his height - 5px. """ dest_x = self.geometry().x() dest_y = self.geometry().y() - self.height() - 5 self.moveTo(dest_x, dest_y) def returnToOriginalPoint(self): """ Panel returns in its original position. The original position is stored when calling moveTo() method. """ if self.__is_moving: return self.__is_moving = True self.__moveAnimation = QPropertyAnimation(self, "pos", self) self.__moveAnimation.finished.connect(self.__on_finished_moving) self.__moveAnimation.setDuration(self.__move_time) self.__moveAnimation.setEasingCurve(self.__move_animation_type) self.__moveAnimation.setStartValue(QPoint(self.pos().x(), self.pos().y())) self.__moveAnimation.setEndValue(self.__starting_position) self.__moveAnimation.start() #FUNZIONI PER RIDIMENSIONAMENTO def setResizeAnimationType(self, animation_type): """ Sets move animation type. @param animation_type: animation type @type animation_type: QtEasingCurve """ self.__resize_animation_type = animation_type def resizeTo(self, width, height): """ Resize itself to a given size with the given animation in the given duration. @param width: New width @type width: int @param height: New height @type height: int """ if self.__is_resizing: return self.__is_resizing = True self.__original_size = self.geometry() self.__resizeAnimation = QPropertyAnimation(self, "geometry", self) self.__resizeAnimation.finished.connect(self.__on_finished_resizing) self.__resizeAnimation.setDuration(self.__resize_time) self.__resizeAnimation.setEasingCurve(self.__resize_animation_type) self.__resizeAnimation.setStartValue(self.__original_size) self.__resizeAnimation.setEndValue(QRect(self.pos().x(), self.pos().y(), width, height)) self.__resizeAnimation.start() def foldLeft(self): """ Panel hides folding to the left. """ new_width = 0 new_height = self.height() self.resizeTo(new_width, new_height) def unfoldLeft(self): """ Panel shows folding from the left. """ new_width = self.__original_size.width() new_height = self.height() self.resizeTo(new_width, new_height) def foldTop(self): """ Panel hides folding to the top. """ new_width = self.width() new_height = 0 self.resizeTo(new_width, new_height) def unfoldTop(self): """ Panel shows folding from the top. """ new_width = self.width() new_height = self.__original_size.height() self.resizeTo(new_width, new_height) #FUNZIONI PER PIXMAP & MASCHERA def setPixmapFile(self, image_file): self.__pmap = image_file self.__pmap.scaled(self.size()) #NB: Il pixmap deve essere BIANCO e NERO. Con heuristicMask il primo pixel in alto a sinistra (0,0) viene #usato per decidere il colore trasparente, tutto il resto è visibile. def getPixmapFile(self): return self.__pmap pixmapFile = QtCore.pyqtProperty("QPixmap", getPixmapFile, setPixmapFile) def applyMask(self, bool): self.__show_mask_preview = bool if bool: self.setMask(QBitmap(self.__pmap.createHeuristicMask().scaled(self.size()))) else: self.setMask(QBitmap()) def getMask(self): return self.__show_mask_preview appliedMask = QtCore.pyqtProperty("bool", fget=getMask, fset=applyMask) def __on_finished_moving(self): self.__is_moving = False def __on_finished_resizing(self): self.__is_resizing = False def __onResize(self, event): self.__pmap.scaled(self.size()) if self.__show_mask_preview: self.setMask(QBitmap(self.__pmap.createHeuristicMask().scaled(self.size()))) #FUNZIONI PER SHADOW def getShadow(self): return self._shadow_visible def setShadow(self, bool): self.setGraphicsEffect(self.__shadow_effect) self._shadow_visible = bool self.__shadow_effect.setEnabled(bool) shadow = QtCore.pyqtProperty("bool", fget=getShadow, fset=setShadow) def setShadowXOffset(self, value): """ Sets shadow offset on X. @param value: offset @type value: float """ self.__shadow_Xoffset = value self.__shadow_effect.setXOffset(self.__shadow_Xoffset) def getShadowXOffset(self): return self.__shadow_Xoffset shadowXOffset = QtCore.pyqtProperty("double", getShadowXOffset, setShadowXOffset) def setShadowYOffset(self, value): """ Sets shadow offset on Y. @param value: offset @type value: float """ self.__shadow_Yoffset = value self.__shadow_effect.setYOffset(self.__shadow_Yoffset) def getShadowYOffset(self): return self.__shadow_Yoffset shadowYOffset = QtCore.pyqtProperty("double", getShadowYOffset, setShadowYOffset) def setShadowBlur(self, value): """ Sets blurred effect on item's shadow. @param value: coefficient @type value: float """ self.__shadow_blur_radius = value self.__shadow_effect.setBlurRadius(self.__shadow_blur_radius) def getShadowBlur(self): return self.__shadow_blur_radius shadowBlur = QtCore.pyqtProperty("double", getShadowBlur, setShadowBlur) def setShadowColor(self, color): """ Sets shadow's color. @param color: value @type color: color """ self.__shadow_color = color self.__shadow_effect.setColor(self.__shadow_color) def getShadowColor(self): return self.__shadow_color
class OWLegend(QGraphicsObject): """ A legend for :obj:`.OWPlot`. Its items are arranged into a hierarchy by `category`. This is useful when points differ in more than one attribute. In such a case, there can be one category for point color and one for point shape. Usually the category name will be the name of the attribute, while the item's title will be the value. Arbitrary categories can be created, for an example see :meth:`.OWPlot.update_axes`, which creates a special category for unused axes. decimals .. image:: files/legend-categories.png In the image above, `type` and `milk` are categories with 7 and 2 possible values, respectively. """ def __init__(self, graph, scene): QGraphicsObject.__init__(self) if scene: scene.addItem(self) self.graph = graph self.curves = [] self.items = {} self.attributes = [] self.point_attrs = {} self.point_vals = {} self.default_values = { PointColor : Qt.black, PointSize : 8, PointSymbol : OWPoint.Ellipse } self.box_rect = QRectF() self.setFiltersChildEvents(True) self.setFlag(self.ItemHasNoContents, True) self.mouse_down = False self._orientation = Qt.Vertical self.max_size = QSizeF() self._floating = True self._floating_animation = None self._mouse_down_pos = QPointF() def clear(self): """ Removes all items from the legend """ for lst in self.items.values(): for i in lst: i.setParentItem(None) if self.scene(): self.scene().removeItem(i) self.items = {} self.update_items() def add_curve(self, curve): """ Adds a legend item with the same point symbol and name as ``curve``. If the curve's name contains the equal sign (=), it is split at that sign. The first part of the curve is a used as the category, and the second part as the value. """ i = curve.name.find('=') if i == -1: cat = '' name = curve.name else: cat = curve.name[:i] name = curve.name[i+1:] self.add_item(cat, name, curve.point_item(0, 0, 0)) def add_item(self, category, value, point): """ Adds an item with title ``value`` and point symbol ``point`` to the specified ``category``. """ if category not in self.items: self.items[category] = [OWLegendTitle(category, self)] self.items[category].append(OWLegendItem(str(value), point, self)) self.update_items() def add_color_gradient(self, title, values): if len(values) < 2: # No point in showing a gradient with less that two values return if title in self.items: self.remove_category(title) item = OWLegendGradient(self.graph.contPalette, [str(v) for v in values], self) self.items[title] = [OWLegendTitle(title, self), item] self.update_items() def remove_category(self, category): """ Removes ``category`` and all items that belong to it. """ if category not in self.items: return if self.scene(): for item in self.items[category]: self.scene().removeItem(item) del self.items[category] def update_items(self): """ Updates the legend, repositioning the items according to the legend's orientation. """ self.box_rect = QRectF() x = y = 0 for lst in self.items.values(): for item in lst: if hasattr(item, 'text_item'): item.text_item.setDefaultTextColor(self.graph.color(OWPalette.Text)) if hasattr(item, 'rect_item'): item.rect_item.setBrush(self.graph.color(OWPalette.Canvas)) if hasattr(item, 'set_orientation'): item.set_orientation(self._orientation) if self._orientation == Qt.Vertical: for lst in self.items.values(): for item in lst: if self.max_size.height() and y and y + item.boundingRect().height() > self.max_size.height(): y = 0 x = x + item.boundingRect().width() self.box_rect = self.box_rect | item.boundingRect().translated(x, y) move_item_xy(item, x, y, self.graph.animate_plot) y = y + item.boundingRect().height() elif self._orientation == Qt.Horizontal: for lst in self.items.values(): max_h = max(item.boundingRect().height() for item in lst) for item in lst: if self.max_size.width() and x and x + item.boundingRect().width() > self.max_size.width(): x = 0 y = y + max_h self.box_rect = self.box_rect | item.boundingRect().translated(x, y) move_item_xy(item, x, y, self.graph.animate_plot) x = x + item.boundingRect().width() if lst: x = 0 y = y + max_h def mouseMoveEvent(self, event): self.graph.notify_legend_moved(event.scenePos()) if self._floating: p = event.scenePos() - self._mouse_down_pos if self._floating_animation and self._floating_animation.state() == QPropertyAnimation.Running: self.set_pos_animated(p) else: self.setPos(p) event.accept() def mousePressEvent(self, event): self.setCursor(Qt.ClosedHandCursor) self.mouse_down = True self._mouse_down_pos = event.scenePos() - self.pos() event.accept() def mouseReleaseEvent(self, event): self.unsetCursor() self.mouse_down = False self._mouse_down_pos = QPointF() event.accept() def boundingRect(self): return self.box_rect def paint(self, painter, option, widget=None): pass def set_orientation(self, orientation): """ Sets the legend's orientation to ``orientation``. """ self._orientation = orientation self.update_items() def orientation(self): return self._orientation def set_pos_animated(self, pos): if (self.pos() - pos).manhattanLength() < 6 or not self.graph.animate_plot: self.setPos(pos) else: t = 250 if self._floating_animation and self._floating_animation.state() == QPropertyAnimation.Running: t = t - self._floating_animation.currentTime() self._floating_animation.stop() self._floating_animation = QPropertyAnimation(self, 'pos') self._floating_animation.setEndValue(pos) self._floating_animation.setDuration(t) self._floating_animation.start(QPropertyAnimation.KeepWhenStopped) def set_floating(self, floating, pos=None): """ If floating is ``True``, the legend can be dragged with the mouse. Otherwise, it's fixed in its position. If ``pos`` is specified, the legend is moved there. """ if floating == self._floating: return self._floating = floating if pos: if floating: self.set_pos_animated(pos - self._mouse_down_pos) else: self.set_pos_animated(pos)
class CImprovedButton(QToolButton): def __init__(self, parent=None): QToolButton.__init__(self, parent) #TESTO ALTERNATIVO #Spesso se il pulsante ha icona troppo grossa e quando per ragioni di spazio o altro non si può spostare #o ridimensionare il pulsante stesso, la label ha posizioni assurde e schifose. Aggiungerne una "+ controllabile" #è l'unico modo.. self.__fixed_label = QLabel("alternative label", self) self.__fixed_label.move(0, self.geometry().height() - 35) self.__fixed_label.resize(self.geometry().width(), self.__fixed_label.geometry().height()) self.__fixed_label.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) self.__font = QtGui.QFont("Arial", 10) self.__fixed_label.setFont(self.__font) self.__fixed_label.show() #INDICATORE STILE iOS self.__indicator = QLabel("0", self) self.__indicator.setStyleSheet("border-image: url(':/images/backgrounds/indicator.png'); padding-right:1px; color: white;") self.__indicator.geometry().setWidth(25) self.__indicator.geometry().setHeight(20) self.__indicator.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) self.__indicator.setVisible(False) self.setIndicatorPos(QPoint(self.width() - self.__indicator.width(), 0)) #default top-right corner #Quando il pulsante viene ridimensionato (designer o meno) devo anche sistemare la label di conseguenza self.resizeEvent = self.__onResize self.__indicator.resizeEvent = self.__on_indicator_Resize self.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) self.clicked.connect(self.stopAllAnimations) #BLINK self.__blink_timer = QTimer(parent) self.__blink_timer.timeout.connect(self.__on_blink_timer) self.__blink_timer_interval = 1000 #FADING self.__opacity_effect = QGraphicsOpacityEffect() self.__fading_timer = QTimer(parent) self.__fading_timer.timeout.connect(self.__on_fading_timer) self.__FADE_TYPE = Enum("IN", "OUT") self.__fade_time = 20 self.__opacity = 1.0 self.__opacity_fading_coefficient = 0.02 self.__selected_fade_type = self.__FADE_TYPE.IN # ANIMAZIONI GROW self.__animationGrow = QPropertyAnimation(self, "iconSize", self) self.__animationGrow.setDuration(1000) self.__animationGrow.setEasingCurve(QEasingCurve.Linear) self.__animationGrow.finished.connect(self.__on_growed) self.__animationShrink = QPropertyAnimation(self, "iconSize", self) self.__animationShrink.setDuration(1000) self.__animationShrink.setEasingCurve(QEasingCurve.Linear) self.__animationShrink.finished.connect(self.__on_shrinked) self.__defaultIconDimension = 60 self.__iconGrowsBy = 40 self.__growing = False # ANIMAZIONI BOUNCE self.__animationUp = QPropertyAnimation(self, "pos", self) self.__animationUp.setDuration(200) self.__animationUp.setEasingCurve(QEasingCurve.Linear) self.__animationUp.finished.connect(self.__on_top_reached) self.__animationBounce = QPropertyAnimation(self, "pos", self) self.__animationBounce.setDuration(1000) self.__animationBounce.setEasingCurve(QEasingCurve.OutBounce) self.__animationBounce.finished.connect(self.__on_bounce_finished) self.__bouncing = False self.__startPos = QPoint(self.pos().x(), self.pos().y()) #PIXMAP & MASCHERA self.__pmap = QPixmap(self.size()) self.__pmap_fname = "" self.__show_mask_preview = False def setDefaultIconSize(self, value): """ Sets default icon size when growing stops. @param value: size (both width and height) @type value: int """ self.__defaultIconDimension = value def getDefaultIconSize(self): return self.__defaultIconDimension defaultIconSize = QtCore.pyqtProperty("int", getDefaultIconSize, setDefaultIconSize) def setFixetTextVisibility(self, bool): """ Sets if fixed text is visible or not. @param bool: visible or not @type bool: bool """ self.__fixed_label.setVisible(bool) def getFixetTextVisibility(self): return self.__fixed_label.isVisible() fixetTextVisibility = QtCore.pyqtProperty("bool", fget=getFixetTextVisibility, fset=setFixetTextVisibility) def setFixedText(self, txt): """ Sets text on the button. @param txt: text @type txt: string """ self.__fixed_label.setText(txt) def getFixedText(self): return self.__fixed_label.text() fixedText = QtCore.pyqtProperty("QString", getFixedText, setFixedText) def setFixedTextPos(self, qpoint): """ Sets text position in the button. @param qpoint: Position RELATIVE. 0,0 is top left corner of the button. @type qpoint: QPoint """ self.__fixed_label.move(qpoint) def getFixedTextPos(self): return self.__fixed_label.pos() fixedTextPos = QtCore.pyqtProperty("QPoint", getFixedTextPos, setFixedTextPos) def setFixedTextFont(self, font): """ Sets text font. @param font: Font for fixed text. @type font: QFont """ self.__font = font self.__fixed_label.setFont(self.__font) def getFixedTextFont(self): return self.__font fixedTextFont = QtCore.pyqtProperty("QFont", getFixedTextFont, setFixedTextFont) #FUNZIONI INDICATORE def setIndicatorVisibility(self, bool): """ Sets if indicator is visible or not. @param bool: visible or not @type bool: bool """ self.__indicator.setVisible(bool) def getIndicatorVisibility(self): return self.__indicator.isVisible() indicatorVisibility = QtCore.pyqtProperty("bool", fget=getIndicatorVisibility, fset=setIndicatorVisibility) def setIndicatorPos(self, qpoint): """ Sets indicator position in the button. @param qpoint: Position RELATIVE. 0,0 is top left corner of the button. @type qpoint: QPoint """ self.__indicator.move(qpoint) def getIndicatorPos(self): return self.__indicator.pos() indicatorPos = QtCore.pyqtProperty("QPoint", getIndicatorPos, setIndicatorPos) def setIndicatorSize(self, size): """ Sets indicator size. @param size: Size @type size: QSize """ self.__indicator.resize(size) def getIndicatorSize(self): return self.__indicator.size() indicatorSize = QtCore.pyqtProperty("QSize", getIndicatorSize, setIndicatorSize) def setIndicatorFont(self, font): """ Sets indicator text font. @param font: Font for indicator text. @type font: QFont """ self.__indicator.setFont(font) def getIndicatorFont(self): return self.__indicator.font() indicatorFont = QtCore.pyqtProperty("QFont", getIndicatorFont, setIndicatorFont) ## FUNZIONI PER BLINK def __on_blink_timer(self): self.setVisible(not (self.isVisible())) def setBlinking(self, blink): """ Sets if the button have to blink or not. @param blink: blinking or not @type blink: bool """ if blink: self.__blink_timer.setInterval(self.__blink_timer_interval) self.__blink_timer.start() else: self.__blink_timer.stop() self.setVisible(True) def setBlinkInterval(self, value): """ Sets blink interval. @param blink: blink interval (msec) @type blink: int """ self.__blink_timer_interval = value def getBlinkInterval(self): return self.__blink_timer_interval blinkInterval = QtCore.pyqtProperty("int", getBlinkInterval, setBlinkInterval) ##FUNZIONI PER FADING def fadeIn(self): """ Button fades in from completely invisible to completely visible. """ self.__opacity = 0.0 self.__selected_fade_type = self.__FADE_TYPE.IN self.__fading_timer.start(self.__fade_time) def fadeOut(self): """ Button fades out from completely visible to completely invisible. """ self.__selected_fade_type = self.__FADE_TYPE.OUT self.__fading_timer.start(self.__fade_time) def setFadeTime(self, value): """ Sets fading time. Everytime interval is reached, alpha is increased (or decreased) by __opacity_fading_coefficient. @param value: fade time (msec) @type value: int """ self.__fade_time = value def getFadeTime(self): return self.__fade_time fadeInterval = QtCore.pyqtProperty("int", getFadeTime, setFadeTime) def setFadeCoefficient(self, value): """ Sets fading coefficient. Alpha is increased (or decreased) by this value. @param value: coefficient (min 0.0 - max 1.0) @type value: float """ self.__opacity_fading_coefficient = value def getFadeCoefficient(self): return self.__opacity_fading_coefficient fadeCoefficient = QtCore.pyqtProperty("double", getFadeCoefficient, setFadeCoefficient) def __on_fading_timer(self): if self.__selected_fade_type == self.__FADE_TYPE.OUT: if self.__opacity > 0: self.__opacity -= self.__opacity_fading_coefficient self.__opacity_effect.setOpacity(self.__opacity) self.setGraphicsEffect(self.__opacity_effect) else: self.__fading_timer.stop() if self.__selected_fade_type == self.__FADE_TYPE.IN: if self.__opacity <= 1.0: self.__opacity += self.__opacity_fading_coefficient self.__opacity_effect.setOpacity(self.__opacity) self.setGraphicsEffect(self.__opacity_effect) else: self.__fading_timer.stop() # FUNZIONI PER GROW\SHRINK def __on_growed(self): self.__animationShrink.setStartValue(QSize(self.iconSize().width(), self.iconSize().height())) self.__animationShrink.setEndValue( QSize(self.iconSize().width() - self.__iconGrowsBy, self.iconSize().height() - self.__iconGrowsBy)) self.__animationShrink.start() def __on_shrinked(self): self.__animationGrow.setStartValue(QSize(self.iconSize().width(), self.iconSize().height())) self.__animationGrow.setEndValue( QSize(self.iconSize().width() + self.__iconGrowsBy, self.iconSize().height() + self.__iconGrowsBy)) self.__animationGrow.start() def startGrow(self): """ Button ICON starts to grow and shrink to standard value when maximum size (configured) is reached """ if self.__growing: return self.__animationGrow.setStartValue(QSize(self.iconSize().width(), self.iconSize().height())) self.__animationGrow.setEndValue( QSize(self.iconSize().width() + self.__iconGrowsBy, self.iconSize().height() + self.__iconGrowsBy)) self.__animationGrow.start() self.__growing = True def stopGrow(self): if self.__animationGrow.startValue().toSize() != QSize(0, 0) and self.__animationShrink.startValue().toSize() != QPoint( 0, 0): self.__animationGrow.stop() self.__animationShrink.stop() self.setIconSize(QSize(self.__defaultIconDimension, self.__defaultIconDimension)) self.__growing = False #FUNZIONI PER BOUNCE def startBounce(self): """ Button starts to bounce requiring attention. """ if self.__bouncing: return self.__startPos = QPoint(self.pos().x(), self.pos().y()) self.__animationUp.setStartValue(QPoint(self.__startPos.x(), self.__startPos.y())) self.__animationUp.setEndValue(QPoint(self.__startPos.x(), self.__startPos.y() - self.geometry().height())) self.__animationUp.start() self.__bouncing = True def stopBounce(self): if self.__animationUp.startValue().toPoint() != QPoint(0,0) and self.__animationBounce.startValue().toPoint() != QPoint(0,0): self.__animationBounce.stop() self.__animationUp.stop() self.setGeometry(self.__startPos.x(), self.__startPos.y(), self.geometry().width(), self.geometry().height()) self.__bouncing = False def __on_top_reached(self): self.__animationBounce.setStartValue(QPoint(self.pos().x(), self.pos().y())) self.__animationBounce.setEndValue(QPoint(self.__startPos.x(), self.__startPos.y())) self.__animationBounce.start() def __on_bounce_finished(self): self.__animationUp.start() def stopAllAnimations(self): self.stopBounce() self.stopGrow() #FUNZIONI PER PIXMAP & MASCHERA def setPixmapFile(self, image_file): self.__pmap = image_file self.__pmap.scaled(self.size()) #NB: Il pixmap deve essere BIANCO e NERO. Con heuristicMask il primo pixel in alto a sinistra (0,0) viene #usato per decidere il colore trasparente, tutto il resto è visibile. def getPixmapFile(self): return self.__pmap pixmapFile = QtCore.pyqtProperty("QPixmap", getPixmapFile, setPixmapFile) def applyMask(self, bool): self.__show_mask_preview = bool if bool: self.setMask(QBitmap(self.__pmap.createHeuristicMask().scaled(self.size()))) else: self.setMask(QBitmap()) def getMask(self): return self.__show_mask_preview appliedMask = QtCore.pyqtProperty("bool", fget=getMask, fset=applyMask) def __onResize(self, event): self.__fixed_label.move(0, self.geometry().height() - 35) self.__fixed_label.resize(self.geometry().width(), self.__fixed_label.geometry().height()) self.setIndicatorPos(QPoint(self.width() - self.__indicator.width(), 0)) self.__pmap.scaled(self.size()) if self.__show_mask_preview: self.setMask(QBitmap(self.__pmap.createHeuristicMask().scaled(self.size()))) def __on_indicator_Resize(self, event): self.setIndicatorPos(QPoint(self.width() - self.__indicator.width(), 0))
def slideIn(self, index, direction=Direction.Automatic): """ Slides in the panel at the inputed index in the given direction for this widget. :param index | <int> direction | <XStackedWidget.Direction> :return <bool> | success """ # do not allow multiple slides while it is active if self._active: return False # determine the proper index to calculate invert = False if self.count() <= index: if not self.wrap(): return False index = self.count() % index invert = True elif index < 0: if not self.wrap(): return False index = self.count() + index invert = True # define the direction information if index == self.currentIndex(): return False elif self.currentIndex() < index: if direction == XStackedWidget.Direction.Automatic: if self.isVerticalMode(): direction = XStackedWidget.Direction.BottomToTop else: direction = XStackedWidget.Direction.RightToLeft else: if direction == XStackedWidget.Direction.Automatic: if self.isVerticalMode(): direction = XStackedWidget.Direction.TopToBottom else: direction = XStackedWidget.Direction.LeftToRight # invert the animation if we are wrapping if invert: if direction == XStackedWidget.Direction.BottomToTop: direction = XStackedWidget.Direction.TopToBottom elif direction == XStackedWidget.Direction.TopToBottom: direction = XStackedWidget.Direction.BottomToTop elif direction == XStackedWidget.Direction.LeftToRight: direction = XStackedWidget.Direction.RightToLeft else: direction = XStackedWidget.Direction.LeftToRight self._active = True offset_x = self.frameRect().width() offset_y = self.frameRect().height() next_widget = self.widget(index) curr_widget = self.widget(self.currentIndex()) next_widget.setGeometry(0, 0, offset_x, offset_y) if direction == XStackedWidget.Direction.BottomToTop: offset_x = 0 offset_y = -offset_y elif direction == XStackedWidget.Direction.TopToBottom: offset_x = 0 elif direction == XStackedWidget.Direction.RightToLeft: offset_x = -offset_x offset_y = 0 elif direction == XStackedWidget.Direction.LeftToRight: offset_y = 0 next_point = next_widget.pos() curr_point = curr_widget.pos() self._nextIndex = index self._lastIndex = self.currentIndex() self._lastPoint = QPoint(curr_point) next_widget.move(next_point.x() - offset_x, next_point.y() - offset_y) next_widget.raise_() next_widget.show() curr_anim = QPropertyAnimation(curr_widget, 'pos') curr_anim.setDuration(self.speed()) curr_anim.setEasingCurve(self.animationType()) curr_anim.setStartValue(curr_point) curr_anim.setEndValue( QPoint(curr_point.x() + offset_x, curr_point.y() + offset_y)) next_anim = QPropertyAnimation(next_widget, 'pos') next_anim.setDuration(self.speed()) next_anim.setEasingCurve(self.animationType()) next_anim.setStartValue( QPoint(next_point.x() - offset_x, next_point.y() - offset_y)) next_anim.setEndValue(next_point) anim_group = QParallelAnimationGroup(self) anim_group.addAnimation(curr_anim) anim_group.addAnimation(next_anim) anim_group.finished.connect(self._finishAnimation) anim_group.finished.connect(anim_group.deleteLater) anim_group.start() return True
class AnimatedStackedWidget(QFrame): # Current widget has changed currentChanged = Signal(int) # Transition animation has started transitionStarted = Signal() # Transition animation has finished transitionFinished = Signal() def __init__(self, parent=None, animationEnabled=True): QFrame.__init__(self, parent) self.__animationEnabled = animationEnabled layout = StackLayout() self.__fadeWidget = CrossFadePixmapWidget(self) self.transitionAnimation = \ QPropertyAnimation(self.__fadeWidget, "blendingFactor_", self) self.transitionAnimation.setStartValue(0.0) self.transitionAnimation.setEndValue(1.0) self.transitionAnimation.setDuration(100 if animationEnabled else 0) self.transitionAnimation.finished.connect( self.__onTransitionFinished ) layout.addWidget(self.__fadeWidget) layout.currentChanged.connect(self.__onLayoutCurrentChanged) self.setLayout(layout) self.__widgets = [] self.__currentIndex = -1 self.__nextCurrentIndex = -1 def setAnimationEnabled(self, animationEnabled): """ Enable/disable transition animations. """ if self.__animationEnabled != animationEnabled: self.__animationEnabled = animationEnabled self.transitionAnimation.setDuration( 100 if animationEnabled else 0 ) def animationEnabled(self): """ Is the transition animation enabled. """ return self.__animationEnabled def addWidget(self, widget): """ Append the widget to the stack and return its index. """ return self.insertWidget(self.layout().count(), widget) def insertWidget(self, index, widget): """ Insert `widget` into the stack at `index`. """ index = min(index, self.count()) self.__widgets.insert(index, widget) if index <= self.__currentIndex or self.__currentIndex == -1: self.__currentIndex += 1 return self.layout().insertWidget(index, widget) def removeWidget(self, widget): """ Remove `widget` from the stack. .. note:: The widget is hidden but is not deleted. """ index = self.__widgets.index(widget) self.layout().removeWidget(widget) self.__widgets.pop(index) def widget(self, index): """ Return the widget at `index` """ return self.__widgets[index] def indexOf(self, widget): """ Return the index of `widget` in the stack. """ return self.__widgets.index(widget) def count(self): """ Return the number of widgets in the stack. """ return max(self.layout().count() - 1, 0) def setCurrentWidget(self, widget): """ Set the current shown widget. """ index = self.__widgets.index(widget) self.setCurrentIndex(index) def setCurrentIndex(self, index): """ Set the current shown widget index. """ index = max(min(index, self.count() - 1), 0) if self.__currentIndex == -1: self.layout().setCurrentIndex(index) self.__currentIndex = index return # if not self.animationEnabled(): # self.layout().setCurrentIndex(index) # self.__currentIndex = index # return # else start the animation current = self.__widgets[self.__currentIndex] next_widget = self.__widgets[index] current_pix = QPixmap.grabWidget(current) next_pix = QPixmap.grabWidget(next_widget) with updates_disabled(self): self.__fadeWidget.setPixmap(current_pix) self.__fadeWidget.setPixmap2(next_pix) self.__nextCurrentIndex = index self.__transitionStart() def currentIndex(self): """ Return the current shown widget index. """ return self.__currentIndex def sizeHint(self): hint = QFrame.sizeHint(self) if hint.isEmpty(): hint = QSize(0, 0) return hint def __transitionStart(self): """ Start the transition. """ log.debug("Stack transition start (%s)", str(self.objectName())) # Set the fade widget as the current widget self.__fadeWidget.blendingFactor_ = 0.0 self.layout().setCurrentWidget(self.__fadeWidget) self.transitionAnimation.start() self.transitionStarted.emit() def __onTransitionFinished(self): """ Transition has finished. """ log.debug("Stack transition finished (%s)" % str(self.objectName())) self.__fadeWidget.blendingFactor_ = 1.0 self.__currentIndex = self.__nextCurrentIndex with updates_disabled(self): self.layout().setCurrentIndex(self.__currentIndex) self.transitionFinished.emit() def __onLayoutCurrentChanged(self, index): # Suppress transitional __fadeWidget current widget if index != self.count(): self.currentChanged.emit(index)
class OWLegend(QGraphicsObject): """ A legend for :obj:`.OWPlot`. Its items are arranged into a hierarchy by `category`. This is useful when points differ in more than one attribute. In such a case, there can be one category for point color and one for point shape. Usually the category name will be the name of the attribute, while the item's title will be the value. Arbitrary categories can be created, for an example see :meth:`.OWPlot.update_axes`, which creates a special category for unused axes. decimals .. image:: files/legend-categories.png In the image above, `type` and `milk` are categories with 7 and 2 possible values, respectively. """ def __init__(self, graph, scene): QGraphicsObject.__init__(self) if scene: scene.addItem(self) self.graph = graph self.curves = [] self.items = {} self.attributes = [] self.point_attrs = {} self.point_vals = {} self.default_values = { PointColor: Qt.black, PointSize: 8, PointSymbol: OWPoint.Ellipse } self.box_rect = QRectF() self.setFiltersChildEvents(True) self.setFlag(self.ItemHasNoContents, True) self.mouse_down = False self._orientation = Qt.Vertical self.max_size = QSizeF() self._floating = True self._floating_animation = None self._mouse_down_pos = QPointF() def clear(self): """ Removes all items from the legend """ for lst in self.items.itervalues(): for i in lst: i.setParentItem(None) if self.scene(): self.scene().removeItem(i) self.items = {} self.update_items() def add_curve(self, curve): """ Adds a legend item with the same point symbol and name as ``curve``. If the curve's name contains the equal sign (=), it is split at that sign. The first part of the curve is a used as the category, and the second part as the value. """ i = curve.name.find('=') if i == -1: cat = '' name = curve.name else: cat = curve.name[:i] name = curve.name[i + 1:] self.add_item(cat, name, curve.point_item(0, 0, 0)) def add_item(self, category, value, point): """ Adds an item with title ``value`` and point symbol ``point`` to the specified ``category``. """ if category not in self.items: self.items[category] = [OWLegendTitle(category, self)] self.items[category].append(OWLegendItem(str(value), point, self)) self.update_items() def add_color_gradient(self, title, values): if len(values) < 2: # No point in showing a gradient with less that two values return if title in self.items: self.remove_category(title) item = OWLegendGradient(self.graph.contPalette, [str(v) for v in values], self) self.items[title] = [OWLegendTitle(title, self), item] self.update_items() def remove_category(self, category): """ Removes ``category`` and all items that belong to it. """ if category not in self.items: return if self.scene(): for item in self.items[category]: self.scene().removeItem(item) del self.items[category] def update_items(self): """ Updates the legend, repositioning the items according to the legend's orientation. """ self.box_rect = QRectF() x = y = 0 for lst in self.items.itervalues(): for item in lst: if hasattr(item, 'text_item'): item.text_item.setDefaultTextColor( self.graph.color(OWPalette.Text)) if hasattr(item, 'rect_item'): item.rect_item.setBrush(self.graph.color(OWPalette.Canvas)) if hasattr(item, 'set_orientation'): item.set_orientation(self._orientation) if self._orientation == Qt.Vertical: for lst in self.items.itervalues(): for item in lst: if self.max_size.height() and y and y + item.boundingRect( ).height() > self.max_size.height(): y = 0 x = x + item.boundingRect().width() self.box_rect = self.box_rect | item.boundingRect( ).translated(x, y) move_item_xy(item, x, y, self.graph.animate_plot) y = y + item.boundingRect().height() elif self._orientation == Qt.Horizontal: for lst in self.items.itervalues(): max_h = max(item.boundingRect().height() for item in lst) for item in lst: if self.max_size.width() and x and x + item.boundingRect( ).width() > self.max_size.width(): x = 0 y = y + max_h self.box_rect = self.box_rect | item.boundingRect( ).translated(x, y) move_item_xy(item, x, y, self.graph.animate_plot) x = x + item.boundingRect().width() if lst: x = 0 y = y + max_h def mouseMoveEvent(self, event): self.graph.notify_legend_moved(event.scenePos()) if self._floating: p = event.scenePos() - self._mouse_down_pos if self._floating_animation and self._floating_animation.state( ) == QPropertyAnimation.Running: self.set_pos_animated(p) else: self.setPos(p) event.accept() def mousePressEvent(self, event): self.setCursor(Qt.ClosedHandCursor) self.mouse_down = True self._mouse_down_pos = event.scenePos() - self.pos() event.accept() def mouseReleaseEvent(self, event): self.unsetCursor() self.mouse_down = False self._mouse_down_pos = QPointF() event.accept() def boundingRect(self): return self.box_rect def paint(self, painter, option, widget=None): pass def set_orientation(self, orientation): """ Sets the legend's orientation to ``orientation``. """ self._orientation = orientation self.update_items() def orientation(self): return self._orientation def set_pos_animated(self, pos): if (self.pos() - pos).manhattanLength() < 6 or not self.graph.animate_plot: self.setPos(pos) else: t = 250 if self._floating_animation and self._floating_animation.state( ) == QPropertyAnimation.Running: t = t - self._floating_animation.currentTime() self._floating_animation.stop() self._floating_animation = QPropertyAnimation(self, 'pos') self._floating_animation.setEndValue(pos) self._floating_animation.setDuration(t) self._floating_animation.start(QPropertyAnimation.KeepWhenStopped) def set_floating(self, floating, pos=None): """ If floating is ``True``, the legend can be dragged with the mouse. Otherwise, it's fixed in its position. If ``pos`` is specified, the legend is moved there. """ if floating == self._floating: return self._floating = floating if pos: if floating: self.set_pos_animated(pos - self._mouse_down_pos) else: self.set_pos_animated(pos)
class CImprovedLabel(QLabel): def __init__(self, parent=None, caption=None): QLabel.__init__(self, parent) self.setText(self.accessibleName()) self.setFont(QtGui.QFont("Arial", 12)) self.__separator = chr(004) #Used as separator while scrolling text #BLINK self.__blink_timer = QTimer(parent) self.__blink_timer.timeout.connect(self.__on_blink_timer) self.__blink_timer_interval = 1000 #FADING self.__opacity_effect = QGraphicsOpacityEffect() self.__fading_timer = QTimer(parent) self.__fading_timer.timeout.connect(self.__on_fading_timer) self.__FADE_TYPE = Enum("IN", "OUT") self.__fade_time = 20 self.__opacity = 1.0 self.__opacity_fading_coefficient = 0.02 self.__selected_fade_type = self.__FADE_TYPE.IN #SCROLLING self.__scrolling_timer = QTimer(parent) self.__scrolling_timer.timeout.connect(self.__on_scrolling_timer) self.__scroll_time = 1000 self.__original_text = "" #MOVE self.__move_animation_type = QEasingCurve.Linear self.__move_time = 350 ## FUNZIONI PER BLINK def __on_blink_timer(self): self.setVisible(not (self.isVisible())) def setBlinking(self, blink): """ Sets if the label have to blink or not. @param blink: blinking or not @type blink: bool """ if blink: self.__blink_timer.setInterval(self.__blink_timer_interval) self.__blink_timer.start() else: self.__blink_timer.stop() self.setVisible(True) def setBlinkInterval(self, value): """ Sets blink interval. @param value: blink interval (msec) @type value: int """ self.__blink_timer_interval = value def getBlinkInterval(self): return self.__blink_timer_interval blinkInterval = QtCore.pyqtProperty("int", getBlinkInterval, setBlinkInterval) ##FUNZIONI PER FADING def fadeIn(self): """ Labels fades in from completely invisible to completely visible. """ self.__opacity = 0.0 self.__selected_fade_type = self.__FADE_TYPE.IN self.__fading_timer.start(self.__fade_time) def fadeOut(self): """ Labels fades out from completely visible to completely invisible. """ self.__selected_fade_type = self.__FADE_TYPE.OUT self.__fading_timer.start(self.__fade_time) def setFadeTime(self, value): """ Sets fading time. Everytime interval is reached, alpha is increased (or decreased) by __opacity_fading_coefficient. @param value: fade time (msec) @type value: int """ self.__fade_time = value def getFadeTime(self): return self.__fade_time fadeInterval = QtCore.pyqtProperty("int", getFadeTime, setFadeTime) def setFadeCoefficient(self, value): """ Sets fading coefficient. Alpha is increased (or decreased) by this value. @param value: coefficient (min 0.0 - max 1.0) @type value: float """ self.__opacity_fading_coefficient = value def getFadeCoefficient(self): return self.__opacity_fading_coefficient fadeCoefficient = QtCore.pyqtProperty("double", getFadeCoefficient, setFadeCoefficient) def __on_fading_timer(self): if self.__selected_fade_type == self.__FADE_TYPE.OUT: if self.__opacity > 0: self.__opacity -= self.__opacity_fading_coefficient self.__opacity_effect.setOpacity(self.__opacity) self.setGraphicsEffect(self.__opacity_effect) else: self.__fading_timer.stop() if self.__selected_fade_type == self.__FADE_TYPE.IN: if self.__opacity <= 1.0: self.__opacity += self.__opacity_fading_coefficient self.__opacity_effect.setOpacity(self.__opacity) self.setGraphicsEffect(self.__opacity_effect) else: self.__fading_timer.stop() #FUNZIONI PER SCROLLING def __move_text_left(self): if self.__separator not in self.text(): self.setText(self.text() + " " + self.__separator + " ") left = str(self.text())[:1] right = str(self.text())[1:] self.setText(right + left) def __on_scrolling_timer(self): self.__move_text_left() def scrollingText(self, scroll): """ Sets if the label have to scroll or not. @param scroll: scrolling right to left or not @type scroll: bool """ self.__scrolling_timer.setInterval(self.__scroll_time) if scroll: self.__original_text = self.text() self.__scrolling_timer.start() else: self.__scrolling_timer.stop() self.setText(self.__original_text) def setScrollingTime(self, value): """ Sets scrolling time. Everytime interval is reached, string is scrolled to left by one char. @param value: scrolling time (msec) @type value: int """ self.__scroll_time = value ## FUNZIONI PER SPOSTAMENTO VERSO PUNTO (ANIMATO) def setMoveAnimationType(self, animation_type): """ Sets move animation type. @param animation_type: animation type @type animation_type: QtEasingCurve """ self.__move_animation_type = animation_type def getMoveAnimationType(self): return self.__move_animation_type #asd = QtCore.pyqtProperty("QEasingCurve", getMoveAnimationType, setMoveAnimationType) #sembra nn essere supportato per ora (06/05/2013) def setMoveTime(self, value): """ Sets animation moving time. @param value: animation time (duration) (msec) @type value: int """ self.__move_time = value def moveTo(self, x, y): """ Move itself to a given point with the given animation in the given duration. @param x: X point coordinate @type x: int @param y: Y point coordinate @type y: int """ self.__starting_position = QPoint(self.pos()) self.__moveAnimation = QPropertyAnimation(self, "pos", self) self.__moveAnimation.setDuration(self.__move_time) self.__moveAnimation.setEasingCurve(self.__move_animation_type) self.__moveAnimation.setStartValue(self.__starting_position) self.__moveAnimation.setEndValue(QPoint(x, y)) self.__moveAnimation.start() def returnToOriginalPoint(self): """ Label returns to its original position. The original position is stored when calling moveTo() method. """ self.__moveAnimation = QPropertyAnimation(self, "pos", self) self.__moveAnimation.setDuration(self.__move_time) self.__moveAnimation.setEasingCurve(self.__move_animation_type) self.__moveAnimation.setStartValue( QPoint(self.pos().x(), self.pos().y())) self.__moveAnimation.setEndValue(self.__starting_position) self.__moveAnimation.start() def mousePressEvent(self, event): self.clicked.emit()
class myGraphicsSvgItem(QtSvg.QGraphicsSvgItem): def __init__(self, parent=None, limitRect=QtCore.QRectF(0, 0, 1000, 1000), cursorShape=QtCore.Qt.OpenHandCursor, name=None, *args, **kwargs): super(myGraphicsSvgItem, self).__init__(parent, *args, **kwargs) self.anim_slide = None self.anim_tilt = None self.anim_fade = None self.center = self.boundingRect().center() self.cursorShape = cursorShape self.limitRect = QtCore.QRectF(limitRect) self.table_widget = self.getWidget('interactiveTable') self.fields_widget = self.getWidget('grdFields') # self.fields_widget = self.parentWidget() self.setCursor(cursorShape) self.setObjectName(name) self.updateCenter() def itemChange(self, change, value): if change == QtGui.QGraphicsItem.ItemPositionChange: new_value = value.toPointF() if not self.limitRect.contains(new_value): new_value.setX( min(self.limitRect.right(), max(new_value.x(), self.limitRect.left()))) new_value.setY( min(self.limitRect.bottom(), max(new_value.y(), self.limitRect.top()))) # print new_value, ' <---- NOT Contains' value = QtCore.QVariant(new_value) return QtGui.QGraphicsItem.itemChange(self, change, value) if change == QtGui.QGraphicsItem.ItemPositionHasChanged: pass return QtGui.QGraphicsItem.itemChange(self, change, value) def mousePressEvent(self, event): print "-----------------" self.setCursor(QtCore.Qt.ClosedHandCursor) pos, item = self.getItemAtMousePos_byMouseEvent(event) print "Press", pos, item.objectName() if item else None self.doAanim_tilt(False) super(myGraphicsSvgItem, self).mousePressEvent(event) def mouseReleaseEvent(self, event): print "-----" self.setCursor(self.cursorShape) pos, item = self.getItemAtMousePos_byMouseEvent(event) print "Release", pos, item.objectName() if item else None self.doAnim_slideTiltFade(item, doTilting=True) # self.anim_do_slide(item) # self.anim_do_tilt(False) super(myGraphicsSvgItem, self).mouseReleaseEvent(event) def getWidget(self, name): wdg = pyChezzApp.findChildren( (QtGui.QWidget, QtGui.QFrame, QtGui.QSpacerItem), QtCore.QString(name))[0] return wdg def getItemAtMousePos_byMouseEvent(self, event): posGlobal = self.table_widget.mapToGlobal(self.pos().toPoint()) posLocal = self.fields_widget.mapFromGlobal(posGlobal) widget = self.fields_widget.childAt(posLocal) return posLocal, widget def getWidgetAtTablePos(self, pos): posGlobal = self.table_widget.mapToGlobal(pos) posLocal = self.fields_widget.mapFromGlobal(posGlobal) widget = self.fields_widget.childAt(posLocal) return widget def move_to_pos(self, pos, duration=200): wdg = self.getWidgetAtTablePos(pos.toPoint()) self.doAnim_slide(wdg, duration) def doAnim_slideTiltFade(self, to_widget, doTilting=False, isBecomeVisible=False, duration=400): self.anim_group = QtCore.QParallelAnimationGroup() self.doAnim_slide(to_widget, duration=duration, doStart=False) self.anim_group.addAnimation(self.anim_slide) if doTilting: isTilted = abs(self.rotation()) > 1.0 self.doAanim_tilt(isTilted, duration=duration, doStart=False) self.anim_group.addAnimation(self.anim_tilt) if isBecomeVisible: self.doAanim_fade(isBecomeVisible, duration=duration, doStart=False) self.anim_group.addAnimation(self.anim_fade) self.anim_group.start() def doAnim_slide(self, to_widget, duration=200, doStart=True): if to_widget is None: self.anim_slide = None return posGlobal = self.fields_widget.mapToGlobal( to_widget.geometry().center()) posLocal = self.table_widget.mapFromGlobal(posGlobal) self.anim_slide = QPropertyAnimation(self, "pos") self.anim_slide.setDuration(duration) self.anim_slide.setStartValue(self.pos()) self.anim_slide.setEndValue(posLocal) self.anim_slide.setEasingCurve(QtCore.QEasingCurve.InOutQuint) if doStart: self.anim_slide.start() return self.anim_slide def doAanim_tilt(self, isTilted, duration=400, doStart=True): self.anim_tilt = QPropertyAnimation(self, "rotation") self.anim_tilt.setDuration(duration) self.anim_tilt.setStartValue(-30 if isTilted else 0) self.anim_tilt.setEndValue(0 if isTilted else -30) self.anim_tilt.setEasingCurve(QtCore.QEasingCurve.OutBack) if doStart: self.anim_tilt.start() return self.anim_tilt def doAanim_fade(self, isBecomeVisible, duration=400, doStart=True): self.anim_fade = QPropertyAnimation(self, "opacity") self.anim_fade.setDuration(duration) self.anim_fade.setStartValue(0.0 if isBecomeVisible else 1.0) self.anim_fade.setEndValue(1.0 if isBecomeVisible else 0.0) self.anim_fade.setEasingCurve(QtCore.QEasingCurve.InCirc) if doStart: self.anim_fade.start() return self.anim_fade def updateCenter(self): self.center = self.boundingRect().center() self.setTransformOriginPoint(self.center) print '________\n' \ 'Name: {},\n' \ 'Pos: {},\n' \ 'Bound: {},\n' \ 'Center: {}\n' \ 'Origin: {}'.format(self.objectName(), self.pos(), self.boundingRect(), self.boundingRect().center(), self.transformOriginPoint())
class pyChezzWin(QtGui.QWidget, form_class): """ GUI class for chess using minimal number of widgets, no AI, on intuitive surface """ __widgetInst__ = None __build__ = 56 def __init__(self, app=None): if not self.__widgetInst__: __widgetInst__ = app super(pyChezzWin, self).__init__() self.setupUi(self) self.interactiveBoardView = QtGui.QGraphicsView(self) self.scene = QtGui.QGraphicsScene(self.interactiveBoardView) self.baseViewRect = QtCore.QRect() # figures, icons and fields self.fields = {} self.snapPoints = [] self.icons = {} self.figures = {} # Connections QtCore.QObject.connect(self.verticalSlider, QtCore.SIGNAL("valueChanged(int)"), self.valueHandlerSlider) QtCore.QObject.connect(self.btnOpen, QtCore.SIGNAL("clicked()"), self.btnOpen_Clicked) QtCore.QObject.connect(self.btnSave, QtCore.SIGNAL("clicked()"), self.btnSave_Clicked) QtCore.QObject.connect(self.scene, QtCore.SIGNAL("clicked()"), self.btnOpen_Clicked) # self.resizeEvent = self.alignTable # game self.myLogFile = '' self.myFigColor = 'light' # TODO: place common data-variables into the gameData dict! Replace references in the code! # self.gameStarted = False self.gameData = {} self.opponentName = 'OPPONENT' self.whoAmI = '' self.isGameStarted = False self.gameData['users'] = {'OPPONENT': 'dark'} def show(self): super(pyChezzWin, self).show() self.setFixedSize(self.size()) self.frmIndicatorYOU.hide() self.initializeBoard() self.alignTable(self) self.drawFigures() self.drawIcons() self.baseViewRect = self.interactiveBoardView.geometry() self.collectSnapPoints() self.enableFigures(self.darkFigures, state=False) self.enableFigures(self.lightFigures, state=False) # self.interactiveBoardView.setCursor(QtCore.Qt.OpenHandCursor) print "Shown!!!" # print "view + scene ---> ", self.interactiveBoardView.rect(), self.interactiveBoardView.sceneRect() self.setAnimations() @property def whoAmI(self): return self.gameData['whoAmI'] @whoAmI.setter def whoAmI(self, name=None): self.gameData['whoAmI'] = name print "I\'am: ", name @property def opponentName(self): return self.gameData['opponentName'] @opponentName.setter def opponentName(self, name): self.gameData['opponentName'] = name @property def isGameStarted(self): return self.gameData['gameStarted'] @isGameStarted.setter def isGameStarted(self, state): self.gameData['gameStarted'] = state def btnOpen_Clicked(self): self.openDataFile() def btnSave_Clicked(self): self.saveNewDataFile() self.isGameStarted = True def valueHandlerSlider(self, value): # FIXME: users data recognition must be fixed !!!! if self.gameData['users'].keys().count(getpass.getuser()): if value: # opponent turn #self.interactiveBoardView.setEnabled(False) self.enableFigures(self.darkFigures, state=False) self.enableFigures(self.lightFigures, state=False) self.frmIndicatorME.hide() self.frmIndicatorYOU.show() self.saveChezzMinData() else: # my turn # self.interactiveBoardView.setEnabled(True) self.enableFigures(self.darkFigures) self.enableFigures(self.lightFigures) self.frmIndicatorME.show() self.frmIndicatorYOU.hide() self.loadChezzMinData() def saveNewDataFile(self): # openfile = QtGui.QFileDialog.getOpenFileName(self, filter='*.czz') openfile = QtGui.QFileDialog.getSaveFileName(self, filter='*.czz') # dialog success if openfile != '': # existing file if os.path.isfile(openfile): msgBox = QtGui.QMessageBox() msgBox.setText("Over write is forbiden!") msgBox.exec_() return self.saveNewDataFile() # new file will be created else: open(openfile, 'w') self.myLogFile = openfile self.saveChezzMinData() file_info = QtCore.QFileInfo(openfile) self.btnOpen.setText(file_info.fileName()) return True else: return False def openDataFile(self): # openfile = QtGui.QFileDialog.getOpenFileName(self, filter='*.czz') openfile = QtGui.QFileDialog.getOpenFileName(self, filter='*.czz') # dialog success if os.path.isfile(openfile): f = open(openfile, 'r') self.myLogFile = openfile file_info = QtCore.QFileInfo(openfile) self.btnOpen.setText(file_info.fileName()) self.initGame() self.loadChezzMinData() self.isGameStarted = True return True else: return False def alignTable(self, null): if self.baseViewRect.width() > 0: targetRect = self.interactiveBoardView.geometry() xForm = QtGui.QMatrix() width_ratio = float(targetRect.width()) / self.baseViewRect.width() height_ratio = float( targetRect.height()) / self.baseViewRect.height() xForm.scale(width_ratio, height_ratio) self.interactiveBoardView.setMatrix(xForm) # self.interactiveBoardView.fitInView(QtCore.QRectF(0, 0, targetRect.width(), targetRect.height())) def initializeBoard(self): self.interactiveBoardView.setRenderHints( QtGui.QPainter.Antialiasing | QtGui.QPainter.SmoothPixmapTransform) self.interactiveBoardView.setStyleSheet( "background-color: transparent;") self.interactiveBoardView.setFrameShape(QtGui.QFrame.NoFrame) self.interactiveBoardView.setObjectName("interactiveTable") self.interactiveBoardView.setScene(self.scene) self.interactiveBoardView.setInteractive(True) self.interactiveBoardView.setHorizontalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff) self.interactiveBoardView.setVerticalScrollBarPolicy( QtCore.Qt.ScrollBarAlwaysOff) self.verticalSlider.setEnabled(False) self.pebleOppLight.setVisible(False) self.pebleMyDark.setVisible(False) self.whoAmI = getpass.getuser() self.gameData['users'][self.whoAmI] = 'light' print 'Users: ', self.gameData['users'] # fit sceneRect targetRect = self.frmOpponentPark.geometry() targetRect.setBottom(self.frmMyPark.geometry().bottom()) self.interactiveBoardView.setGeometry(targetRect) self.interactiveBoardView.setSceneRect(0, 0, targetRect.width(), targetRect.height()) # collecting field widgets from UI file for row in range(1, 9): for col in 'ABCDEFGH': fld = eval('self.field%s%s' % (col, row)) self.fields['{}{}'.format( col, row)] = fld # self.fields['A1'] = self.fieldA1 def startNewGame(self): if self.saveChezzMinData(): self.initGame() def initGame(self, state=True): self.isGameStarted = state self.icons['rotateIcon'].setVisible(False) self.icons['goIcon'].setVisible(False) self.enableFigures(self.darkFigures) self.enableFigures(self.lightFigures) self.btnSave.setVisible(False) self.verticalSlider.setEnabled(True) # whois next !! print 'Game Started!!!' def setAnimations(self): self.anim_rotateIcon = QPropertyAnimation(self.icons["rotateIcon"], "rotation") self.anim_rotateIcon.setDuration(300) self.anim_rotateIcon.setStartValue(0) self.anim_rotateIcon.setEndValue(360) # self.anim_rotateBoard = QPropertyAnimation(self.interactiveBoardView, "rotate") # self.anim_rotateBoard.setDuration(300) # self.anim_rotateBoard.setStartValue(0) # self.anim_rotateBoard.setEndValue(180) # self.anim_unRotateBoard = QPropertyAnimation(self.interactiveBoardView, "rotate") # self.anim_unRotateBoard.setDuration(300) # self.anim_unRotateBoard.setStartValue(180) # self.anim_unRotateBoard.setEndValue(0) def rotateBoard(self): self.anim_rotateIcon.start() boardRect = self.interactiveBoardView.frameRect() goIconRect = self.icons["goIcon"].boundingRect() if self.myFigColor.find('light') == 0: self.interactiveBoardView.rotate(180) # self.grdFields.rotate(180) # self.anim_rotateBoard.start() pos = QtCore.QPointF( boardRect.width() / 2 + goIconRect.width() / 2, boardRect.height() / 2 - 60) self.icons["goIcon"].setPos(pos) self.icons["goIcon"].rotate(180) for key, fig in self.figures.iteritems(): fig.rotate(180) fig.moveBy(1.5, 2) self.pebleOppLight.setVisible(True) self.pebleOppDark.setVisible(False) self.pebleMyLight.setVisible(False) self.pebleMyDark.setVisible(True) self.myFigColor = 'dark' else: self.interactiveBoardView.rotate(-180) pos = QtCore.QPointF( boardRect.width() / 2 - goIconRect.width() / 2, boardRect.height() / 2 + 60) self.icons["goIcon"].setPos(pos) self.icons["goIcon"].rotate(180) for key, fig in self.figures.iteritems(): fig.rotate(180) fig.moveBy(-1.5, -2) self.pebleOppLight.setVisible(False) self.pebleOppDark.setVisible(True) self.pebleMyLight.setVisible(True) self.pebleMyDark.setVisible(False) self.myFigColor = 'light' # self.users['dark'], self.users['light'] = (self.users['light'], self.users['dark']) # self.users[self.users.keys()[0]], self.users[self.users.keys()[1]] = (self.users.values()[1], self.users.values()[0]) self.gameData['users'][self.gameData['users'].keys()[0]], self.gameData['users'][self.gameData['users'].keys()[1]] =\ (self.gameData['users'].values()[1], self.gameData['users'].values()[0]) print 'Users: ', self.gameData['users'] def getFiguresByAttribute(self, attr='name', value='light'): return { k: v for k, v in self.figures.iteritems() if color in eval('v.{}'.format(name)) } def drawFigures(self): imagesPath = os.path.dirname(__file__) + "/images/" limitRect = self.interactiveBoardView.frameRect() self.darkFigures = { "darkKing": ChessFigure(imagesPath + "kdt.svg", limitRect=limitRect, name='darkKing', startField='E8'), "darkQueen": ChessFigure(imagesPath + "qdt.svg", limitRect=limitRect, name='darkQueen', startField='D8'), "darkBishop1": ChessFigure(imagesPath + "bdt.svg", limitRect=limitRect, name='darkBishop1', startField='C8'), "darkBishop2": ChessFigure(imagesPath + "bdt.svg", limitRect=limitRect, name='darkBishop2', startField='F8'), "darkKnight1": ChessFigure(imagesPath + "ndt.svg", limitRect=limitRect, name='darkKnight1', startField='B8'), "darkKnight2": ChessFigure(imagesPath + "ndt.svg", limitRect=limitRect, name='darkKnight2', startField='G8'), "darkRook1": ChessFigure(imagesPath + "rdt.svg", limitRect=limitRect, name='darkRook1', startField='A8'), "darkRook2": ChessFigure(imagesPath + "rdt.svg", limitRect=limitRect, name='darkRook2', startField='H8'), "darkPawn1": ChessFigure(imagesPath + "pdt.svg", limitRect=limitRect, name='darkPawn1', startField='A7'), "darkPawn2": ChessFigure(imagesPath + "pdt.svg", limitRect=limitRect, name='darkPawn2', startField='B7'), "darkPawn3": ChessFigure(imagesPath + "pdt.svg", limitRect=limitRect, name='darkPawn3', startField='C7'), "darkPawn4": ChessFigure(imagesPath + "pdt.svg", limitRect=limitRect, name='darkPawn4', startField='D7'), "darkPawn5": ChessFigure(imagesPath + "pdt.svg", limitRect=limitRect, name='darkPawn5', startField='E7'), "darkPawn6": ChessFigure(imagesPath + "pdt.svg", limitRect=limitRect, name='darkPawn6', startField='F7'), "darkPawn7": ChessFigure(imagesPath + "pdt.svg", limitRect=limitRect, name='darkPawn7', startField='G7'), "darkPawn8": ChessFigure(imagesPath + "pdt.svg", limitRect=limitRect, name='darkPawn8', startField='H7') } self.lightFigures = { "lightKing": ChessFigure(imagesPath + "klt.svg", limitRect=limitRect, name='lightKing', startField='E1'), "lightQueen": ChessFigure(imagesPath + "qlt.svg", limitRect=limitRect, name='lightQueen', startField='D1'), "lightBishop1": ChessFigure(imagesPath + "blt.svg", limitRect=limitRect, name='lightBishop1', startField='C1'), "lightBishop2": ChessFigure(imagesPath + "blt.svg", limitRect=limitRect, name='lightBishop2', startField='F1'), "lightKnight1": ChessFigure(imagesPath + "nlt.svg", limitRect=limitRect, name='lightKnight1', startField='B1'), "lightKnight2": ChessFigure(imagesPath + "nlt.svg", limitRect=limitRect, name='lightKnight2', startField='G1'), "lightRook1": ChessFigure(imagesPath + "rlt.svg", limitRect=limitRect, name='lightRook1', startField='A1'), "lightRook2": ChessFigure(imagesPath + "rlt.svg", limitRect=limitRect, name='lightRook2', startField='H1'), "lightPawn1": ChessFigure(imagesPath + "plt.svg", limitRect=limitRect, name='lightPawn1', startField='A2'), "lightPawn2": ChessFigure(imagesPath + "plt.svg", limitRect=limitRect, name='lightPawn2', startField='B2'), "lightPawn3": ChessFigure(imagesPath + "plt.svg", limitRect=limitRect, name='lightPawn3', startField='C2'), "lightPawn4": ChessFigure(imagesPath + "plt.svg", limitRect=limitRect, name='lightPawn4', startField='D2'), "lightPawn5": ChessFigure(imagesPath + "plt.svg", limitRect=limitRect, name='lightPawn5', startField='E2'), "lightPawn6": ChessFigure(imagesPath + "plt.svg", limitRect=limitRect, name='lightPawn6', startField='F2'), "lightPawn7": ChessFigure(imagesPath + "plt.svg", limitRect=limitRect, name='lightPawn7', startField='G2'), "lightPawn8": ChessFigure(imagesPath + "plt.svg", limitRect=limitRect, name='lightPawn8', startField='H2') } self.figures = {} self.figures.update(self.darkFigures) self.figures.update(self.lightFigures) for key, fig in self.figures.iteritems(): fig.setFlag(QtGui.QGraphicsItem.ItemIsMovable, True) fig.setFlag(QtGui.QGraphicsItem.ItemIsSelectable, True) fig.setFlag(QtGui.QGraphicsItem.ItemSendsGeometryChanges, True) fig.setTransformOriginPoint(-fig.boundingRect().width() - 4, -fig.boundingRect().height() - 4) # fig.updateCenter() fig.setScale(0.7) fig.setObjectName(key) self.scene.addItem(fig) # place figures to initial pos for fig, figInf in self.darkFigures.iteritems(): print fig, figInf.startField self.moveFigureToField(fig, figInf.startField) figInf.currentField = figInf.startField for fig, figInf in self.lightFigures.iteritems(): self.moveFigureToField(fig, figInf.startField) figInf.currentField = figInf.startField # print "%s - %s" % (fig, figInf['startField']) def drawIcons(self): imagesPath = os.path.dirname(__file__) + "/images/" limitRect = self.interactiveBoardView.frameRect() # rotateIcon self.icons["rotateIcon"] = myGraphicsSvgItem( imagesPath + "rotate_square.svg", cursorShape=QtCore.Qt.PointingHandCursor, name="rotateIcon") self.scene.addItem(self.icons["rotateIcon"]) iconRect = self.icons["rotateIcon"].boundingRect() self.icons["rotateIcon"].setPos( QtCore.QPointF(limitRect.bottomRight() / 2) - iconRect.bottomRight() / 2) # goIcon self.icons["goIcon"] = myGraphicsSvgItem( imagesPath + "GO.svg", cursorShape=QtCore.Qt.PointingHandCursor, name="goIcon") self.scene.addItem(self.icons["goIcon"]) iconRect = self.icons["goIcon"].boundingRect() self.icons["goIcon"].setPos( QtCore.QPointF(limitRect.width() / 2 - iconRect.width() / 2, limitRect.height() / 2 + 60)) def getItemAtMousePos_byMEvent(self, e): posGlobal = self.mapToGlobal(e.pos()) posLocal = self.interactiveBoardView.mapFromGlobal(posGlobal) item = self.interactiveBoardView.itemAt(posLocal) return item def mousePressEvent(self, QMouseEvent): item = self.getItemAtMousePos_byMEvent(QMouseEvent) if item is not None: if str(item.objectName()).find('rotateIcon') == 0: self.rotateBoard() if str(item.objectName()).find('goIcon') == 0: self.startNewGame() print "Pressed: ", item.objectName() def enableFigures(self, figures, state=True): for fig in figures: self.figures[fig].setFlag(QtGui.QGraphicsItem.ItemIsSelectable, state) self.figures[fig].setFlag(QtGui.QGraphicsItem.ItemIsMovable, state) def placeIcon(self, iconName, iconPos): pass def removeIcon(self, iconName): pass def moveFigureToField(self, figName, fldName, rndSpeed=400): fig = self.figures[figName] fld = self.fields[fldName] rnd = random() * rndSpeed if fig.pos() == QtCore.QPoint(0, 0): board_geo = self.interactiveBoardView.geometry() rnd_x = random() * (board_geo.width() - 10) + 5 rnd_y = board_geo.height() / 2.0 fig.setPos(rnd_x, rnd_y) fig.doAnim_slideTiltFade(fld, isBecomeVisible=True, duration=2000 + rnd) else: fig.doAnim_slideTiltFade(fld, duration=400 + rnd) def moveFigureToPos(self, figName, pos, rndSpeed=600): fig = self.figures[figName] rnd = random() * rndSpeed fig.move_to_pos(pos, duration=1200 + rnd) def getFieldCenter(self, fldName): fld = self.fields[fldName] fldCenterOffset = QtCore.QPoint(fld.geometry().center()) - fld.pos() return fld.mapToGlobal(fldCenterOffset) def collectSnapPoints(self): self.snapPoints = [] for key, fld in self.fields.iteritems(): fldCoordGlobal = self.getFieldCenter(key) fldCoordLocal = self.interactiveBoardView.mapFromGlobal( fldCoordGlobal) self.snapPoints.append(fldCoordLocal) rectOpp = self.frmOpponentPark.geometry() rectSpace = QtCore.QPoint(rectOpp.width() / 9, rectOpp.height() / 3) for i in range(rectSpace.x(), 8 * rectSpace.x(), rectSpace.x()): for j in range(rectSpace.y(), rectSpace.y() * 3, rectSpace.y()): boardCoordGlob = self.frmOpponentPark.mapToGlobal( QtCore.QPoint(i, j)) fldCoordLocal = self.interactiveBoardView.mapFromGlobal( boardCoordGlob) self.snapPoints.append(fldCoordLocal) rectMy = self.frmMyPark.geometry() # TODO: Complete collecting parking points for snap # print self.snapPoints def saveChezzMinData(self): if self.myLogFile: self.gameDataexport_dict = {} figPlaces = {} for key, item in self.figures.iteritems(): figPlaces[str(item.objectName())] = (item.pos().x(), item.pos().y()) time = strftime("%Y-%m-%d %H:%M:%S", gmtime()) self.gameData['fileDataType'] = ('pyChezzMin', 'v0.1.{}'.format(self.__build__), '*****@*****.**') self.gameData[ 'gameStarted'] = time if 'gameStarted' not in self.gameData else self.gameData[ 'gameStarted'] self.gameData['figPlaces'] = figPlaces self.gameData['whoIsNext'] = ( self.gameData['whoAmI'], self.gameData['opponentName'])[self.verticalSlider.value()] json_data = json.dumps(self.gameData, sort_keys=True, indent=4, separators=(',', ': ')) try: with open(self.myLogFile, "w") as log: log.write(json_data) finally: print "Saved!" return True else: return self.saveNewDataFile() def loadChezzMinData(self): json_data = {} # if log file written and has data if self.myLogFile and int(os.stat(self.myLogFile).st_size): try: with open(self.myLogFile, "r") as log: json_data = json.loads(log.read()) except: print "Cannot read data file!" else: # loaded and check if the user is part of the game if self.whoAmI in json_data['users'].keys(): self.gameData = json_data mySavedColor = [ col for per, col in json_data['users'].iteritems() if per == self.whoAmI ][0] if mySavedColor != self.myFigColor: # flip the board if necessary self.rotateBoard() print 'rotated on load' self.myFigColor = mySavedColor # self.setGameStarted() # turnIndex = ('ME', 'OPPONENT').index(json_data['whoIsNext']) turnIndex = (self.whoAmI, self.opponentName).index( json_data['whoIsNext']) # self.verticalSlider.setValue(turnIndex) for key, value in json_data['figPlaces'].iteritems(): self.moveFigureToPos( key, QtCore.QPointF(value[0], value[1])) print "Loaded!" else: print "You are not parted in this game!" print 'Loaded: ', json_data
class CLightBlueSwitch(QSlider): ''' classdocs ''' styleKnob = 'QSlider::handle:horizontal {border-image: url(:/images/switches/white_round_knob_2.png); border: 0px solid; width: 32px; margin-left: 3px; margin-bottom: 3px; margin-top: 2px;}' styleBkgOFF = 'QSlider::groove:horizontal {border: 1px solid #999999; height: 35px; border-image: url(:/images/switches/off_black_2.png); margin: 1px;};' styleBkgON = 'QSlider::groove:horizontal {border: 1px solid #999999; height: 35px; border-image: url(:/images/switches/on_lblue_1.png); margin: 1px;};' clicked = QtCore.pyqtSignal() animationOk = QtCore.pyqtSignal() def __init__(self, parent=None): ''' Constructor ''' QSlider.__init__(self, parent) self.setOrientation(QtCore.Qt.Horizontal) self.animationType = QEasingCurve.OutExpo self.animation = QPropertyAnimation(self, "value") self.animation.setDuration(250) self.animation.finished.connect(self.animationDone) self.resize(85, 50) self.clicked.connect(self.changeValue) self.setStyleSheet(self.styleKnob + self.styleBkgOFF) def changeValue(self): """Slot utilizzato per cambiare lo stato e la grafica del check.""" self.animation.setEasingCurve(self.animationType) if self.value() == self.maximum(): self.animation.setStartValue(self.maximum()) self.animation.setEndValue(self.minimum()) self.animation.start() self.setStyleSheet(self.styleKnob + self.styleBkgOFF) return else: self.animation.setStartValue(self.minimum()) self.animation.setEndValue(self.maximum()) self.setStyleSheet(self.styleKnob + self.styleBkgON) self.animation.start() @QtCore.pyqtSignature("setAtMax()") def setAtMax(self): if self.value() == self.minimum(): self.animation.setEasingCurve(self.animationType) self.animation.setStartValue(self.minimum()) self.animation.setEndValue(self.maximum()) self.animation.start() self.setStyleSheet(self.styleKnob + self.styleBkgON) @QtCore.pyqtSignature("setAtMin()") def setAtMin(self): if self.value() == self.maximum(): self.animation.setEasingCurve(self.animationType) self.animation.setStartValue(self.maximum()) self.animation.setEndValue(self.minimum()) self.animation.start() self.setStyleSheet(self.styleKnob + self.styleBkgOFF) def mousePressEvent(self, event): self.clicked.emit() def isChecked(self): return (self.value() == self.maximum()) def wheelEvent(self, event): # è uno switch 1\0, quindi devo disabilitare la rotellina del mouse prima che lo slider faccia il lavoro per cui è stato creato.. return def animationDone(self): self.animationOk.emit()
class SplitterResizer(QObject): """An object able to control the size of a widget in a QSpliter instance. """ def __init__(self, parent=None): QObject.__init__(self, parent) self.__splitter = None self.__widget = None self.__animationEnabled = True self.__size = -1 self.__expanded = False self.__animation = QPropertyAnimation(self, b"size_", self) self.__action = QAction("toogle-expanded", self, checkable=True) self.__action.triggered[bool].connect(self.setExpanded) def setSize(self, size): """Set the size of the controlled widget (either width or height depending on the orientation). """ if self.__size != size: self.__size = size self.__update() def size(self): """Return the size of the widget in the splitter (either height of width) depending on the splitter orientation. """ if self.__splitter and self.__widget: index = self.__splitter.indexOf(self.__widget) sizes = self.__splitter.sizes() return sizes[index] else: return -1 size_ = Property(int, fget=size, fset=setSize) def setAnimationEnabled(self, enable): """Enable/disable animation. """ self.__animation.setDuration(0 if enable else 200) def animationEnabled(self): return self.__animation.duration() == 0 def setSplitterAndWidget(self, splitter, widget): """Set the QSplitter and QWidget instance the resizer should control. .. note:: the widget must be in the splitter. """ if splitter and widget and not splitter.indexOf(widget) > 0: raise ValueError("Widget must be in a spliter.") if self.__widget: self.__widget.removeEventFilter() self.__splitter = splitter self.__widget = widget if widget: widget.installEventFilter(self) self.__update() def toogleExpandedAction(self): """Return a QAction that can be used to toggle expanded state. """ return self.__action def open(self): """Open the controlled widget (expand it to it sizeHint). """ self.__expanded = True self.__action.setChecked(True) if not (self.__splitter and self.__widget): return size = self.size() if size > 0: # Already has non zero size. return hint = self.__widget.sizeHint() if self.__splitter.orientation() == Qt.Vertical: end = hint.height() else: end = hint.width() self.__animation.setStartValue(0) self.__animation.setEndValue(end) self.__animation.start() def close(self): """Close the controlled widget (shrink to size 0). """ self.__expanded = False self.__action.setChecked(False) if not (self.__splitter and self.__widget): return self.__animation.setStartValue(self.size()) self.__animation.setEndValue(0) self.__animation.start() def setExpanded(self, expanded): """Set the expanded state. """ if self.__expanded != expanded: if expanded: self.open() else: self.close() def expanded(self): """Return the expanded state. """ return self.__expanded def __update(self): """Update the splitter sizes. """ if self.__splitter and self.__widget: splitter = self.__splitter index = splitter.indexOf(self.__widget) sizes = splitter.sizes() current = sizes[index] diff = current - self.__size sizes[index] = self.__size sizes[index - 1] = sizes[index - 1] + diff self.__splitter.setSizes(sizes) def eventFilter(self, obj, event): if event.type() == QEvent.Resize: if self.__splitter.orientation() == Qt.Vertical: size = event.size().height() else: size = event.size().width() if self.__expanded and size == 0: self.__action.setChecked(False) self.__expanded = False elif not self.__expanded and size > 0: self.__action.setChecked(True) self.__expanded = True return QObject.eventFilter(self, obj, event)
class MiniMap(QPlainTextEdit): 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.setTextInteractionFlags(Qt.NoTextInteraction) self._parent = parent self.highlighter = None styles.set_style(self, 'minimap') self.max_line = 0 self.goe = QGraphicsOpacityEffect() self.setGraphicsEffect(self.goe) self.goe.setOpacity(settings.MINIMAP_MIN_OPACITY) self.animation = QPropertyAnimation(self.goe, "opacity") def __calculate_max(self): first_line = self._parent.firstVisibleBlock().blockNumber() last_line = self._parent._sidebarWidget.highest_line self.max_line = last_line - first_line self.update_visible_area() def set_code(self, source): self.setPlainText(source) self.__calculate_max() def adjust_to_parent(self): self.setFixedHeight(self._parent.height()) self.setFixedWidth(self._parent.width() * settings.SIZE_PROPORTION) x = self._parent.width() - self.width() self.move(x, 0) fontsize = int(self.width() / settings.MARGIN_LINE) if fontsize < 1: fontsize = 1 font = self.document().defaultFont() font.setPointSize(fontsize) self.setFont(font) self.__calculate_max() def update_visible_area(self): block = self._parent.firstVisibleBlock() first_line = block.blockNumber() max_count = self.blockCount() parent_cursor = self._parent.textCursor() parent_cursor.setPosition(block.position()) self.setTextCursor(parent_cursor) lines_count = self.max_line if (first_line + self.max_line) > max_count: lines_count = max_count - first_line extraSelections = [] for i in xrange(lines_count): selection = QTextEdit.ExtraSelection() lineColor = QColor(resources.CUSTOM_SCHEME.get('current-line', resources.COLOR_SCHEME['current-line'])) lineColor.setAlpha(100) selection.format.setBackground(lineColor) selection.format.setProperty(QTextFormat.FullWidthSelection, True) cursor = self.textCursor() cursor.setPosition(block.position()) selection.cursor = cursor selection.cursor.clearSelection() extraSelections.append(selection) block = block.next() self.setExtraSelections(extraSelections) def enterEvent(self, event): self.animation.setDuration(300) self.animation.setStartValue(settings.MINIMAP_MIN_OPACITY) self.animation.setEndValue(settings.MINIMAP_MAX_OPACITY) self.animation.start() def leaveEvent(self, event): self.animation.setDuration(300) self.animation.setStartValue(settings.MINIMAP_MAX_OPACITY) self.animation.setEndValue(settings.MINIMAP_MIN_OPACITY) self.animation.start() def mousePressEvent(self, event): super(MiniMap, self).mousePressEvent(event) cursor = self.cursorForPosition(event.pos()) self._parent.jump_to_line(cursor.blockNumber())
class Preferences(QDialog): def __init__(self, parent=None): QDialog.__init__(self, parent) self.setWindowTitle(self.tr("Configuraciones - Edis")) self.__sections = [] # Opacity effect self.effect = QGraphicsOpacityEffect() self.setGraphicsEffect(self.effect) self.animation = QPropertyAnimation(self.effect, "opacity") Edis.load_component("preferences", self) # Install sections #lint:disable from src.ui.dialogs.preferences import (environment_configuration, editor_configuration, compiler_configuration) #lint:enable self.load_ui() key_escape = QShortcut(QKeySequence(Qt.Key_Escape), self) self.connect(key_escape, SIGNAL("activated()"), self.close) self.connect(self.btn_cancel, SIGNAL("clicked()"), self.close) self.connect(self.btn_guardar, SIGNAL("clicked()"), self._save) def install_section(self, obj): self.__sections.append(obj) def load_ui(self): container = QVBoxLayout(self) box = QHBoxLayout() box.setContentsMargins(0, 0, 0, 0) box.setSpacing(0) toolbar = QToolBar() toolbar.setToolButtonStyle(3) toolbar.setOrientation(Qt.Vertical) toolbar.setIconSize(QSize(30, 30)) toolbar.setObjectName("preferencias") environment_section = toolbar.addAction(QIcon(":image/general-pref"), "Entorno") editor_section = toolbar.addAction(QIcon(":image/editor-pref"), "Editor") compiler_section = toolbar.addAction(QIcon(":image/compiler-pref"), "Compilador") self.connect(environment_section, SIGNAL("triggered()"), lambda: self.change_widget(0)) self.connect(editor_section, SIGNAL("triggered()"), lambda: self.change_widget(1)) self.connect(compiler_section, SIGNAL("triggered()"), lambda: self.change_widget(2)) # Set size for action in toolbar.actions(): widget = toolbar.widgetForAction(action) widget.setFixedSize(80, 50) box.addWidget(toolbar) self.stack = QStackedWidget() box.addWidget(self.stack) # Load sections and subsections for section in self.__sections: for name, obj in list(section.get_tabs().items()): section.install_tab(obj, name) self.stack.addWidget(section) box_buttons = QHBoxLayout() box_buttons.setMargin(10) box_buttons.setSpacing(10) box_buttons.addStretch(1) self.btn_cancel = QPushButton(self.tr("Cancelar")) self.btn_guardar = QPushButton(self.tr("Guardar")) box_buttons.addWidget(self.btn_cancel) box_buttons.addWidget(self.btn_guardar) container.addLayout(box) container.addLayout(box_buttons) def change_widget(self, index): if not self.isVisible(): self.show() self.stack.setCurrentIndex(index) def _save(self): for index in range(self.stack.count()): self.stack.widget(index).save() self.close() def close(self): super(Preferences, self).close() self.emit(SIGNAL("configurationsClose(PyQt_PyObject)"), self) def showEvent(self, event): super(Preferences, self).showEvent(event) self.animation.setDuration(400) self.animation.setStartValue(0) self.animation.setEndValue(1) self.animation.start()
class FileSelector(QDialog): def __init__(self, parent=None): super(FileSelector, self).__init__(parent, Qt.Dialog | Qt.FramelessWindowHint) self.setObjectName("file-selector") self._files = {} self.effect = QGraphicsOpacityEffect() self.setGraphicsEffect(self.effect) self.animation = QPropertyAnimation(self.effect, "opacity") self.animation.setDuration(1500) box = QVBoxLayout(self) box.setSpacing(30) self.list_of_files = QListWidget() self.list_of_files.setObjectName("list-selector") box.addWidget(self.list_of_files) self.label_path = QLabel() box.addWidget(self.label_path) self._load_files() self.connect(self.list_of_files, SIGNAL("itemSelectionChanged()"), self._update_label) self.connect(self.list_of_files, SIGNAL("itemActivated(QListWidgetItem*)"), self._open_file) self.connect(self.list_of_files, SIGNAL("itemEntered(QListWidgetItem*)"), self._open_file) def _load_files(self): """ Carga los archivos abiertos en la lista """ editor_container = Edis.get_component("principal") opened_files = editor_container.opened_files_for_selector() for _file in opened_files: base_name = os.path.basename(_file) self._files[base_name] = _file self.list_of_files.addItem(base_name) index = editor_container.current_index() self.list_of_files.setCurrentRow(index) self._update_label() def _update_label(self): """ Actualiza el QLabel """ item = self.list_of_files.currentItem() show_in_label = self._files.get(item.text()) self.label_path.setText(show_in_label) def _open_file(self, item): """ Cambia de archivo en el stacked """ editor_container = Edis.get_component("principal") index = self.list_of_files.row(item) editor_container.editor_widget.change_item(index) self.close() def showEvent(self, event): super(FileSelector, self).showEvent(event) self.animation.setStartValue(0) self.animation.setEndValue(1) self.animation.start()
def popup(self, pos=None): """ Pops up this widget at the inputed position. The inputed point should \ be in global space. :param pos | <QPoint> :return <bool> success """ if self._first and self.centralWidget() is not None: self.adjustSize() self._first = False if not self.signalsBlocked(): self.aboutToShow.emit() if not pos: pos = QCursor.pos() if self.currentMode() == XPopupWidget.Mode.Dialog and \ self.isVisible(): return False elif self.currentMode() == XPopupWidget.Mode.Dialog: self.setPopupMode() # auto-calculate the point if self.autoCalculateAnchor(): self.setAnchor(self.mapAnchorFrom(self.parent(), pos)) pad = self.popupPadding() # determine where to move based on the anchor anchor = self.anchor() # MODIFY X POSITION # align x-left if (anchor & (XPopupWidget.Anchor.TopLeft | XPopupWidget.Anchor.BottomLeft)): pos.setX(pos.x() - pad) # align x-center elif (anchor & (XPopupWidget.Anchor.TopCenter | XPopupWidget.Anchor.BottomCenter)): pos.setX(pos.x() - self.width() / 2) # align x-right elif ( anchor & (XPopupWidget.Anchor.TopRight | XPopupWidget.Anchor.BottomRight)): pos.setX(pos.x() - self.width() + pad) # align x-padded elif (anchor & (XPopupWidget.Anchor.RightTop | XPopupWidget.Anchor.RightCenter | XPopupWidget.Anchor.RightBottom)): pos.setX(pos.x() - self.width()) # MODIFY Y POSITION # align y-top if (anchor & (XPopupWidget.Anchor.LeftTop | XPopupWidget.Anchor.RightTop)): pos.setY(pos.y() - pad) # align y-center elif (anchor & (XPopupWidget.Anchor.LeftCenter | XPopupWidget.Anchor.RightCenter)): pos.setY(pos.y() - self.height() / 2) # align y-bottom elif (anchor & (XPopupWidget.Anchor.LeftBottom | XPopupWidget.Anchor.RightBottom)): pos.setY(pos.y() - self.height() + pad) # align y-padded elif ( anchor & (XPopupWidget.Anchor.BottomLeft | XPopupWidget.Anchor.BottomCenter | XPopupWidget.Anchor.BottomRight)): pos.setY(pos.y() - self.height()) self.adjustMask() self.move(pos) self.update() self.setUpdatesEnabled(True) if self.isAnimated(): anim = QPropertyAnimation(self, 'windowOpacity') anim.setParent(self) anim.setStartValue(0.0) anim.setEndValue(self.windowOpacity()) anim.setDuration(500) anim.finished.connect(anim.deleteLater) self.setWindowOpacity(0.0) else: anim = None self.show() if self.currentMode() != XPopupWidget.Mode.ToolTip: self.activateWindow() widget = self.centralWidget() if widget: self.centralWidget().setFocus() if anim: anim.start() if not self.signalsBlocked(): self.shown.emit() return True
class MiniMap(QPlainTextEdit): 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, "opacity") self.slider = SliderArea(self) self.slider.show() def __calculate_max(self): line_height = self._parent.cursorRect().height() if line_height > 0: self.lines_count = self._parent.viewport().height() / line_height self.slider.update_position() self.update_visible_area() def set_code(self, source): self.highlighter.highlight_function = self.highlighter.open_highlight self.setPlainText(source) self.__calculate_max() self.highlighter.async_highlight() def adjust_to_parent(self): self.setFixedHeight(self._parent.height()) self.setFixedWidth(self._parent.width() * settings.SIZE_PROPORTION) x = self._parent.width() - self.width() self.move(x, 0) fontsize = int(self.width() / settings.MARGIN_LINE) if fontsize < 1: fontsize = 1 font = self.document().defaultFont() font.setPointSize(fontsize) self.setFont(font) self.__calculate_max() def update_visible_area(self): if not self.slider.pressed: line_number = self._parent.firstVisibleBlock().blockNumber() block = self.document().findBlockByLineNumber(line_number) cursor = self.textCursor() cursor.setPosition(block.position()) rect = self.cursorRect(cursor) self.setTextCursor(cursor) self.slider.move_slider(rect.y()) def enterEvent(self, event): if ACTIVATE_OPACITY: self.animation.setDuration(300) self.animation.setStartValue(settings.MINIMAP_MIN_OPACITY) self.animation.setEndValue(settings.MINIMAP_MAX_OPACITY) self.animation.start() def leaveEvent(self, event): if ACTIVATE_OPACITY: self.animation.setDuration(300) self.animation.setStartValue(settings.MINIMAP_MAX_OPACITY) self.animation.setEndValue(settings.MINIMAP_MIN_OPACITY) self.animation.start() def mousePressEvent(self, event): super(MiniMap, self).mousePressEvent(event) cursor = self.cursorForPosition(event.pos()) self._parent.jump_to_line(cursor.blockNumber()) def resizeEvent(self, event): super(MiniMap, self).resizeEvent(event) self.slider.update_position() def scroll_area(self, pos_parent, pos_slider): pos_parent.setY(pos_parent.y() - pos_slider.y()) cursor = self.cursorForPosition(pos_parent) self._parent.verticalScrollBar().setValue(cursor.blockNumber()) def wheelEvent(self, event): super(MiniMap, self).wheelEvent(event) self._parent.wheelEvent(event)
class MiniMap(QsciScintilla): def __init__(self, editor): super(MiniMap, self).__init__(editor) self._editor = editor self.SendScintilla(QsciScintilla.SCI_SETCARETSTYLE, 0) self.SendScintilla(QsciScintilla.SCI_SETBUFFEREDDRAW, 0) self.SendScintilla(QsciScintilla.SCI_SETHSCROLLBAR, 0) self.SendScintilla(QsciScintilla.SCI_SETVSCROLLBAR, 0) self.SendScintilla(QsciScintilla.SCI_SETZOOM, -10) self.SendScintilla(QsciScintilla.SCI_SETREADONLY, 1) self.SendScintilla(QsciScintilla.SCI_HIDESELECTION, 1) self.SendScintilla(QsciScintilla.SCI_SETCURSOR, 8) # Hide markers for i in range(1, 5): self.SendScintilla( QsciScintilla.SCI_MARKERDEFINE, i, QsciScintilla.SC_MARK_EMPTY) self.SendScintilla(QsciScintilla.SCI_SETMARGINWIDTHN, 1, 0) self.setMouseTracking(True) if ACTIVATE_OPACITY: self.goe = QGraphicsOpacityEffect() self.setGraphicsEffect(self.goe) self.goe.setOpacity(settings.MINIMAP_MIN_OPACITY) self.animation = QPropertyAnimation(self.goe, "opacity") self.animation.setDuration(300) self.slider = SliderArea(self) self.slider.show() def adjust_to_parent(self): self.setFixedHeight(self._editor.height()) self.setFixedWidth(self._editor.width() * settings.SIZE_PROPORTION) x = self._editor.width() - self.width() self.move(x, 0) self.slider.update_position() def shutdown(self): self._editor.SCN_UPDATEUI.disconnect() self._editor.SCN_ZOOM.disconnect() def fold(self, line): self.foldLine(line) def scroll_map(self): first_visible_line = self._editor.SendScintilla( QsciScintilla.SCI_GETFIRSTVISIBLELINE) num_doc_lines = self._editor.SendScintilla( QsciScintilla.SCI_GETLINECOUNT) num_visible_lines = self._editor.SendScintilla( QsciScintilla.SCI_DOCLINEFROMVISIBLE, num_doc_lines) lines_on_screen = self._editor.SendScintilla( QsciScintilla.SCI_LINESONSCREEN) if num_visible_lines > lines_on_screen: last_top_visible_line = num_visible_lines - lines_on_screen num_map_visible_lines = self.SendScintilla( QsciScintilla.SCI_DOCLINEFROMVISIBLE, num_doc_lines) # Lines on screen map lines_on_screenm = self.SendScintilla( QsciScintilla.SCI_LINESONSCREEN) # Last top visible line on map last_top_visible_linem = num_map_visible_lines - lines_on_screenm # Portion covered portion = first_visible_line / last_top_visible_line first_visible_linem = round(last_top_visible_linem * portion) # Scroll self.verticalScrollBar().setValue(first_visible_linem) # Move slider higher_pos = self._editor.SendScintilla( QsciScintilla.SCI_POSITIONFROMPOINT, 0, 0) y = self.SendScintilla( QsciScintilla.SCI_POINTYFROMPOSITION, 0, higher_pos) self.slider.move(0, y) self._current_scroll_value = self._editor.verticalScrollBar().value() def scroll_area(self, pos_parent): line = self.__line_from_position(pos_parent) self._editor.verticalScrollBar().setValue(line) def mousePressEvent(self, event): super(MiniMap, self).mousePressEvent(event) line = self.__line_from_position(event.pos()) self._editor.jump_to_line(line) # Go to center los = self._editor.SendScintilla(QsciScintilla.SCI_LINESONSCREEN) / 2 scroll_value = self._editor.verticalScrollBar().value() if self._current_scroll_value < scroll_value: self._editor.verticalScrollBar().setValue(scroll_value + los) else: self._editor.verticalScrollBar().setValue(scroll_value - los) def __line_from_position(self, point): position = self.SendScintilla(QsciScintilla.SCI_POSITIONFROMPOINT, point.x(), point.y()) return self.SendScintilla(QsciScintilla.SCI_LINEFROMPOSITION, position) def enterEvent(self, event): if ACTIVATE_OPACITY: self.animation.setStartValue(settings.MINIMAP_MIN_OPACITY) self.animation.setEndValue(settings.MINIMAP_MAX_OPACITY) self.animation.start() def leaveEvent(self, event): if ACTIVATE_OPACITY: self.animation.setStartValue(settings.MINIMAP_MAX_OPACITY) self.animation.setEndValue(settings.MINIMAP_MIN_OPACITY) self.animation.start() def wheelEvent(self, event): super(MiniMap, self).wheelEvent(event) self._editor.wheelEvent(event) def resizeEvent(self, event): super(MiniMap, self).resizeEvent(event) self.slider.update_position()
class MainWindow(QtGui.QMainWindow): def __init__(self): super(MainWindow, self).__init__() uic.loadUi(cl.UIstem + 'SDOM.ui', self) self.label.hide() self.toSwitch = None self.setWindowTitle('Super Dope Operations Management') self.showFullScreen() self.label.setPixmap( QtGui.QPixmap("/home/pi/python/SDLabs/SDLOGO.jpg")) self.label.setScaledContents(True) self.actionCustomer_Relations.triggered.connect( lambda: self.pageOpen('customerRelations.py')) self.actionIntake.triggered.connect(lambda: self.pageOpen('intake.py')) self.actionLab.triggered.connect(lambda: self.pageOpen('lab.py')) self.actionFinishing.triggered.connect( lambda: self.pageOpen('finishing.py')) self.actionYield.triggered.connect(lambda: self.pageOpen('yieldW.py')) self.actionProduct_Management.triggered.connect( lambda: self.pageOpen('productManagement.py')) self.actionPackaging.triggered.connect( lambda: self.pageOpen('packaging.py')) self.actionDistillate.triggered.connect( lambda: self.pageOpen('distillate.py')) self.actionPOS.triggered.connect(lambda: self.pageOpen('pos.py')) self.actionIClick.triggered.connect(lambda: self.pageOpen('iclick.py')) self.actionLog_Access.triggered.connect( lambda: self.pageOpen('../../.logAccess/logAccess.py')) self.actionExit.triggered.connect(logClose) self.center() def fadeOutPix(self): self.effect = QtGui.QGraphicsOpacityEffect() self.label.setGraphicsEffect(self.effect) self.anim = QPropertyAnimation(self.effect, "opacity") self.fadeOut() self.anim.finished.connect(self.switch) def fadeInPix(self): self.effect = QtGui.QGraphicsOpacityEffect() self.label.setGraphicsEffect(self.effect) self.anim = QPropertyAnimation(self.effect, "opacity") self.fadeIn() self.anim.finished.connect(self.switch) def fadeIn(self): self.anim.setDuration(1200) self.anim.setStartValue(0.0) self.anim.setEndValue(1.0) self.anim.setEasingCurve(QtCore.QEasingCurve.OutCubic) self.anim.start() def fadeOut(self): self.anim.setDuration(1000) self.anim.setStartValue(1.0) self.anim.setEndValue(0.0) self.anim.setEasingCurve(QtCore.QEasingCurve.OutCubic) self.anim.start() def pageOpen(self, page): self.toSwitch = page self.fadeOut() def center(self): frameGm = self.frameGeometry() screen = QtGui.QApplication.desktop().screenNumber( QtGui.QApplication.desktop().cursor().pos()) centerPoint = QtGui.QApplication.desktop().screenGeometry( screen).center() frameGm.moveCenter(centerPoint) self.move(frameGm.topLeft()) self.label.move(frameGm.topLeft()) def switch(self): if self.toSwitch == None: return elif self.toSwitch == 'quit': exit() elif self.toSwitch == 'start': self.toSwitch = None self.label.show() self.fadeInPix() return self.label.hide() completed = subprocess.call('python ' + self.toSwitch, shell=True) print('returncode:', completed) self.toSwitch = None if completed == 0: self.label.show() self.fadeInPix()
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.init(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()
def __init__(self, parent=None): RoboPart.__init__(self) self.setFlag(QGraphicsItem.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) self.headItem.setPos(0, -18) self.upperLeftArmItem.setPos(-15, -10) self.lowerLeftArmItem.setPos(30, 0) self.upperRightArmItem.setPos(15, -10) self.lowerRightArmItem.setPos(30, 0) self.upperRightLegItem.setPos(10, 32) self.lowerRightLegItem.setPos(30, 0) self.upperLeftLegItem.setPos(-10, 32) self.lowerLeftLegItem.setPos(30, 0) self.animation = QParallelAnimationGroup(None) #self.headAnimation = QPropertyAnimation(self.headItem, "scale") #self.headAnimation.setStartValue(20) #self.headAnimation.setEndValue(-20) #self.headScaleAnimation = QPropertyAnimation(self.headItem, "scale") #self.headScaleAnimation.setEndValue(1.1) #self.animation.addAnimation(self.headAnimation) #self.animation.addAnimation(self.headScaleAnimation) #self.upperLeftArmAnimation = QPropertyAnimation(self.upperLeftArmItem, "rotation") #self.upperLeftArmAnimation.setStartValue(190) #self.upperLeftArmAnimation.setEndValue(180) #self.animation.addAnimation(self.upperLeftArmAnimation) #self.lowerLeftArmAnimation = QPropertyAnimation(self.lowerLeftArmItem, "rotation") #self.lowerLeftArmAnimation.setStartValue(50) #self.lowerLeftArmAnimation.setEndValue(10) #self.animation.addAnimation(self.lowerLeftArmAnimation) #self.upperRightArmAnimation = QPropertyAnimation(self.upperRightArmItem, "rotation") #self.upperRightArmAnimation.setStartValue(300) #self.upperRightArmAnimation.setEndValue(310) #self.animation.addAnimation(self.upperRightArmAnimation) #self.lowerRightArmAnimation = QPropertyAnimation(self.lowerRightArmItem, "rotation") #self.lowerRightArmAnimation.setStartValue(0) #self.lowerRightArmAnimation.setEndValue(-70) #self.animation.addAnimation(self.lowerRightArmAnimation) #self.upperLeftLegAnimation = QPropertyAnimation(self.upperLeftLegItem, "rotation") #self.upperLeftLegAnimation.setStartValue(150) #self.upperLeftLegAnimation.setEndValue(80) #self.animation.addAnimation(self.upperLeftLegAnimation) #self.lowerLeftLegAnimation = QPropertyAnimation(self.lowerLeftLegItem, "rotation") #self.lowerLeftLegAnimation.setStartValue(70) #self.lowerLeftLegAnimation.setEndValue(10) #self.animation.addAnimation(self.lowerLeftLegAnimation) #self.upperRightLegAnimation = QPropertyAnimation(self.upperRightLegItem, "rotation") #self.upperRightLegAnimation.setStartValue(40) #self.upperRightLegAnimation.setEndValue(120) #self.animation.addAnimation(self.upperRightLegAnimation) #self.lowerRightLegAnimation = QPropertyAnimation(self.lowerRightLegItem, "rotation") #self.lowerRightLegAnimation.setStartValue(10) #self.lowerRightLegAnimation.setEndValue(50) #self.animation.addAnimation(self.lowerRightLegAnimation) #self.torsoAnimation = QPropertyAnimation(self.torsoItem, "rotation") #self.torsoAnimation.setStartValue(5) #self.torsoAnimation.setEndValue(-20) #self.animation.addAnimation(self.torsoAnimation) for i in xrange(self.animation.animationCount()): anim = QPropertyAnimation(self.animation.animationAt(i)) anim.setEasingCurve(QEasingCurve.SineCurve) anim.setDuration(2000) self.animation.setLoopCount(-1) self.animation.start()
def popup(self, pos=None): """ Pops up this widget at the inputed position. The inputed point should \ be in global space. :param pos | <QPoint> :return <bool> success """ if self._first and self.centralWidget() is not None: self.adjustSize() self._first = False if not self.signalsBlocked(): self.aboutToShow.emit() if not pos: pos = QCursor.pos() if self.currentMode() == XPopupWidget.Mode.Dialog and \ self.isVisible(): return False elif self.currentMode() == XPopupWidget.Mode.Dialog: self.setPopupMode() # auto-calculate the point if self.autoCalculateAnchor(): self.setAnchor(self.mapAnchorFrom( self.parent(), pos )) pad = self.popupPadding() # determine where to move based on the anchor anchor = self.anchor() # MODIFY X POSITION # align x-left if ( anchor & (XPopupWidget.Anchor.TopLeft | XPopupWidget.Anchor.BottomLeft) ): pos.setX(pos.x() - pad) # align x-center elif ( anchor & (XPopupWidget.Anchor.TopCenter | XPopupWidget.Anchor.BottomCenter) ): pos.setX(pos.x() - self.width() / 2) # align x-right elif ( anchor & (XPopupWidget.Anchor.TopRight | XPopupWidget.Anchor.BottomRight) ): pos.setX(pos.x() - self.width() + pad) # align x-padded elif ( anchor & (XPopupWidget.Anchor.RightTop | XPopupWidget.Anchor.RightCenter | XPopupWidget.Anchor.RightBottom) ): pos.setX(pos.x() - self.width()) # MODIFY Y POSITION # align y-top if ( anchor & (XPopupWidget.Anchor.LeftTop | XPopupWidget.Anchor.RightTop) ): pos.setY(pos.y() - pad) # align y-center elif ( anchor & (XPopupWidget.Anchor.LeftCenter | XPopupWidget.Anchor.RightCenter) ): pos.setY(pos.y() - self.height() / 2) # align y-bottom elif ( anchor & (XPopupWidget.Anchor.LeftBottom | XPopupWidget.Anchor.RightBottom) ): pos.setY(pos.y() - self.height() + pad) # align y-padded elif ( anchor & (XPopupWidget.Anchor.BottomLeft | XPopupWidget.Anchor.BottomCenter | XPopupWidget.Anchor.BottomRight) ): pos.setY(pos.y() - self.height()) self.adjustMask() self.move(pos) self.update() self.setUpdatesEnabled(True) if self.isAnimated(): anim = QPropertyAnimation(self, 'windowOpacity') anim.setParent(self) anim.setStartValue(0.0) anim.setEndValue(self.windowOpacity()) anim.setDuration(500) anim.finished.connect(anim.deleteLater) self.setWindowOpacity(0.0) else: anim = None self.show() if self.currentMode() != XPopupWidget.Mode.ToolTip: self.activateWindow() widget = self.centralWidget() if widget: self.centralWidget().setFocus() if anim: anim.start() if not self.signalsBlocked(): self.shown.emit() return True
class MiniMap(QPlainTextEdit): 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 self.connect(self._parent, SIGNAL("updateRequest(const QRect&, int)"), self.update_visible_area) if ACTIVATE_OPACITY: self.goe = QGraphicsOpacityEffect() self.setGraphicsEffect(self.goe) self.goe.setOpacity(settings.MINIMAP_MIN_OPACITY) self.animation = QPropertyAnimation(self.goe, "opacity") self.slider = SliderArea(self) self.slider.show() def shutdown(self): self.disconnect(self._parent, SIGNAL("updateRequest(const QRect&, int)"), self.update_visible_area) def __calculate_max(self): line_height = self._parent.cursorRect().height() if line_height > 0: self.lines_count = self._parent.viewport().height() / line_height self.slider.update_position() self.update_visible_area() def set_code(self, source): self.setPlainText(source) self.__calculate_max() def adjust_to_parent(self): self.setFixedHeight(self._parent.height()) self.setFixedWidth(self._parent.width() * settings.SIZE_PROPORTION) x = self._parent.width() - self.width() self.move(x, 0) fontsize = int(self.width() / settings.MARGIN_LINE) if fontsize < 1: fontsize = 1 font = self.document().defaultFont() font.setPointSize(fontsize) self.setFont(font) self.__calculate_max() def update_visible_area(self): if not self.slider.pressed: line_number = self._parent.firstVisibleBlock().blockNumber() block = self.document().findBlockByLineNumber(line_number) cursor = self.textCursor() cursor.setPosition(block.position()) rect = self.cursorRect(cursor) self.setTextCursor(cursor) self.slider.move_slider(rect.y()) def enterEvent(self, event): if ACTIVATE_OPACITY: self.animation.setDuration(300) self.animation.setStartValue(settings.MINIMAP_MIN_OPACITY) self.animation.setEndValue(settings.MINIMAP_MAX_OPACITY) self.animation.start() def leaveEvent(self, event): if ACTIVATE_OPACITY: self.animation.setDuration(300) self.animation.setStartValue(settings.MINIMAP_MAX_OPACITY) self.animation.setEndValue(settings.MINIMAP_MIN_OPACITY) self.animation.start() def mousePressEvent(self, event): super(MiniMap, self).mousePressEvent(event) cursor = self.cursorForPosition(event.pos()) self._parent.jump_to_line(cursor.blockNumber()) def resizeEvent(self, event): super(MiniMap, self).resizeEvent(event) self.slider.update_position() def scroll_area(self, pos_parent, pos_slider): pos_parent.setY(pos_parent.y() - pos_slider.y()) cursor = self.cursorForPosition(pos_parent) self._parent.verticalScrollBar().setValue(cursor.blockNumber()) def wheelEvent(self, event): super(MiniMap, self).wheelEvent(event) self._parent.wheelEvent(event)
class CellSkin(Cell): sel_brush = QBrush(QColor("cyan")) sel_pen = QPen(QBrush(QColor("black")), 3) posChanged = pyqtSignal() def __init__(self, cid, data, cons=None, props=None): Cell.__init__(self, cid, data, cons, props) self.skin = None self.old_brush = None self.old_pen = None self.loaded = False self.initialMove = True self.animation = QPropertyAnimation() # Called when we can't find the attribute, probably going # to skin def __getattr__(self, name): if name in self.__dict__: return self.__dict__[name] return self.__dict__["skin"].__getattribute__(name) def __del__(self): if self.skin: del self.skin def getChild(self, num=0): childs = self.skin.childItems() if self.skin and num >= 0 and \ num < len(childs): return childs[num] return None def getSkin(self): return self.skin def add(self, space): if not self.loaded: if not self.skin: self.skin = Skin() self.skin.xChanged.connect(self.posChanged) self.skin.yChanged.connect(self.posChanged) self.skin.zChanged.connect(self.posChanged) self.skin.setPen(QPen(QBrush(QColor("black")), 1)) self.skin.setBrush(QColor("tan")) dlog.debug("adding skin for first time: " + str(self.skin)) space.scene.addItem(self.getSkin()) self.placeChildren(space) self.updateRect() self.skin.setZValue(2) self.initialMove = True else: dlog.debug ("adding item: " + str(self.getSkin())) space.scene.addItem(self.getSkin()) self.loaded = True @pyqtSlot() def updateRect(self): if self.skin: self.skin.setRect(self.skin.childrenBoundingRect()) def setPos(self, center): if self.skin: # setPos works in terms of topLeft, but center point is # easiest on the frontend, so convert rect = self.getSkin().sceneBoundingRect() topLeft = QPointF(center[0] - rect.width()/2, center[1] - rect.height()/2) if self.initialMove: self.skin.setPos(topLeft) self.skin.setTargetPos(topLeft) self.initialMove = False else: self.animation.stop() while self.animation.state() != self.animation.Stopped: pass self.animation.setTargetObject(self.skin) self.animation.setPropertyName("pos") self.animation.setDuration(1000) self.animation.setEndValue(topLeft) self.skin.setTargetPos(topLeft) self.animation.start() def remove(self, scene, cached=True): if not self.loaded: return scene.removeItem(self.getSkin()) self.loaded = False if not cached: self.skin = None def select(self): # subclasses can play with these, so save them self.old_brush = self.skin.brush() self.old_pen = self.skin.pen() self.skin.setBrush(self.sel_brush) self.skin.setPen(self.sel_pen) self.skin.setZValue(8) def deselect(self): if self.old_brush: self.skin.setBrush(self.old_brush) self.skin.setPen(self.old_pen) self.skin.setZValue(2)
class CImprovedStackWidget(QStackedWidget): __SLIDE_TYPE = Enum("TOP2BOTTOM", "BOTTOM2TOP", "RIGHT2LEFT", "LEFT2RIGHT", "AUTOMATIC") animationOk = QtCore.pyqtSignal() def __init__(self, parent=None): """ Inizializza il componente""" QStackedWidget.__init__(self, parent) self.__m_vertical=False self.__m_speed=500 self.__m_animationtype = QEasingCurve.OutQuint #QEasingCurve.OutBack self.__m_now=0 self.__m_next=0 self.__m_pnow=QPoint(0,0) self.__m_active = False self.__direction = self.__SLIDE_TYPE.RIGHT2LEFT self.__animgroup = QtCore.QParallelAnimationGroup() self.__animgroup.finished.connect(self.__animationDone) self.__animnext = QPropertyAnimation(None, "pos") self.__animnow = QPropertyAnimation(None, "pos") #self.setMinimumSize(300, 300) self.setStyleSheet("background-color: rgb(184, 184, 184);") def setVerticalMode(self, bool): """ Setta la modalità slide in verticale @param bool: Impostata a true o false, determina se lo slide è verticale o orizzontale. @type bool: Boolean """ self.__m_vertical = bool def setSpeed(self, speed_value): """ Setta la velocità di slide tra una pagine e l'altra. @param speed_value: Velocità in msec. @type speed_value: int """ self.__m_speed = speed_value def getSpeed(self): return self.__m_speed slidingSpeed = QtCore.pyqtProperty("int", getSpeed, setSpeed) def setAnimation(self, animation_type): """ Setta il la tipologia di animazione da utilizzare per gli slide. @param animation_type: Tipo di animazione. @type animation_type: QEasingCurve """ self.__m_animationtype = animation_type def slideNext(self): """Sposta alla finestra successiva""" now = self.currentIndex() self.slideIdx(now + 1) def slidePrev(self): """Sposta alla finestra precedente""" now = self.currentIndex() self.slideIdx(now - 1) def slideIdx(self, idx): """ Sposta la visualizzazione alla finestra indicata. @param idx: Indice finestra da visualizzare @type idx: int """ if(idx > self.count()-1): if(self.__m_vertical): self.__direction = self.__SLIDE_TYPE.TOP2BOTTOM else: self.__direction = self.__SLIDE_TYPE.RIGHT2LEFT idx = (idx) % self.count() elif (idx<0): if(self.__m_vertical): self.__direction = self.__SLIDE_TYPE.BOTTOM2TOP else: self.__direction = self.__SLIDE_TYPE.LEFT2RIGHT idx = (idx + self.count()) % self.count() self.slideInWgt(self.widget(idx)) def slideInWgt(self, widget): if self.__m_active: return #se l'animazione e' attiva, nn faccio nulla. else: self.__m_active = True now = self.currentIndex() next = self.indexOf(widget) if(now==next): self.__m_active = False return elif(now < next): if(self.__m_vertical): dhint = self.__SLIDE_TYPE.TOP2BOTTOM else: dhint = self.__SLIDE_TYPE.RIGHT2LEFT else: if(self.__m_vertical): dhint = self.__SLIDE_TYPE.BOTTOM2TOP else: dhint = self.__SLIDE_TYPE.LEFT2RIGHT #======================================================================= # if(self.__direction == self.AUTOMATIC): # self.__direction = dhint #======================================================================= self.__direction = dhint offsetX = self.frameRect().width() offsetY = self.frameRect().height() self.widget(next).setGeometry ( 0, 0, offsetX, offsetY ) if (self.__direction==self.__SLIDE_TYPE.BOTTOM2TOP): offsetX=0 offsetY=-offsetY elif (self.__direction==self.__SLIDE_TYPE.TOP2BOTTOM): offsetX=0 elif (self.__direction==self.__SLIDE_TYPE.RIGHT2LEFT): offsetX=-offsetX offsetY=0 elif (self.__direction==self.__SLIDE_TYPE.LEFT2RIGHT): offsetY=0 pnext = self.widget(next).pos() pnow = self.widget(now).pos() self.__m_pnow = pnow self.widget(next).move(pnext.x() - offsetX, pnext.y() - offsetY) self.widget(next).show() self.__animnow.setTargetObject(self.widget(now)) self.__animnow.setDuration(self.__m_speed) self.__animnow.setEasingCurve(self.__m_animationtype) self.__animnow.setStartValue(QPoint(pnow.x(), pnow.y())) self.__animnow.setEndValue(QPoint(offsetX+pnow.x(), offsetY+pnow.y())) self.__animnext.setTargetObject(self.widget(next)) self.__animnext.setDuration(self.__m_speed) self.__animnext.setEasingCurve(self.__m_animationtype) self.__animnext.setStartValue(QPoint(-offsetX+pnext.x(), offsetY+pnext.y())) self.__animnext.setEndValue(QPoint(pnext.x(), pnext.y())) self.__animgroup.addAnimation(self.__animnow) self.__animgroup.addAnimation(self.__animnext) self.__m_next=next self.__m_now=now self.__m_active=True self.__animgroup.start() def __animationDone(self): self.setCurrentIndex(self.__m_next) self.widget(self.__m_now).hide() self.widget(self.__m_now).move(self.__m_pnow) self.__m_active=False self.animationOk.emit()
class MiniMap(QsciScintilla): def __init__(self, editor): super(MiniMap, self).__init__(editor) self._editor = editor self.SendScintilla(QsciScintilla.SCI_SETCARETSTYLE, 0) self.SendScintilla(QsciScintilla.SCI_SETBUFFEREDDRAW, 0) self.SendScintilla(QsciScintilla.SCI_SETHSCROLLBAR, 0) self.SendScintilla(QsciScintilla.SCI_SETVSCROLLBAR, 0) self.SendScintilla(QsciScintilla.SCI_SETZOOM, -10) self.SendScintilla(QsciScintilla.SCI_SETREADONLY, 1) self.SendScintilla(QsciScintilla.SCI_HIDESELECTION, 1) self.SendScintilla(QsciScintilla.SCI_SETCURSOR, 8) # Hide markers for i in range(1, 5): self.SendScintilla(QsciScintilla.SCI_MARKERDEFINE, i, QsciScintilla.SC_MARK_EMPTY) self.SendScintilla(QsciScintilla.SCI_SETMARGINWIDTHN, 1, 0) self.setMouseTracking(True) if ACTIVATE_OPACITY: self.goe = QGraphicsOpacityEffect() self.setGraphicsEffect(self.goe) self.goe.setOpacity(settings.MINIMAP_MIN_OPACITY) self.animation = QPropertyAnimation(self.goe, "opacity") self.animation.setDuration(300) self.slider = SliderArea(self) self.slider.show() def adjust_to_parent(self): self.setFixedHeight(self._editor.height()) self.setFixedWidth(self._editor.width() * settings.SIZE_PROPORTION) x = self._editor.width() - self.width() self.move(x, 0) self.slider.update_position() def shutdown(self): self._editor.SCN_UPDATEUI.disconnect() self._editor.SCN_ZOOM.disconnect() def fold(self, line): self.foldLine(line) def scroll_map(self): first_visible_line = self._editor.SendScintilla( QsciScintilla.SCI_GETFIRSTVISIBLELINE) num_doc_lines = self._editor.SendScintilla( QsciScintilla.SCI_GETLINECOUNT) num_visible_lines = self._editor.SendScintilla( QsciScintilla.SCI_DOCLINEFROMVISIBLE, num_doc_lines) lines_on_screen = self._editor.SendScintilla( QsciScintilla.SCI_LINESONSCREEN) if num_visible_lines > lines_on_screen: last_top_visible_line = num_visible_lines - lines_on_screen num_map_visible_lines = self.SendScintilla( QsciScintilla.SCI_DOCLINEFROMVISIBLE, num_doc_lines) # Lines on screen map lines_on_screenm = self.SendScintilla( QsciScintilla.SCI_LINESONSCREEN) # Last top visible line on map last_top_visible_linem = num_map_visible_lines - lines_on_screenm # Portion covered portion = first_visible_line / last_top_visible_line first_visible_linem = round(last_top_visible_linem * portion) # Scroll self.verticalScrollBar().setValue(first_visible_linem) # Move slider higher_pos = self._editor.SendScintilla( QsciScintilla.SCI_POSITIONFROMPOINT, 0, 0) y = self.SendScintilla(QsciScintilla.SCI_POINTYFROMPOSITION, 0, higher_pos) self.slider.move(0, y) self._current_scroll_value = self._editor.verticalScrollBar().value() def scroll_area(self, pos_parent, line_area): line = self.__line_from_position(pos_parent) self._editor.verticalScrollBar().setValue(line - line_area) def mousePressEvent(self, event): super(MiniMap, self).mousePressEvent(event) line = self.__line_from_position(event.pos()) self._editor.jump_to_line(line) # Go to center los = self._editor.SendScintilla(QsciScintilla.SCI_LINESONSCREEN) / 2 scroll_value = self._editor.verticalScrollBar().value() if self._current_scroll_value < scroll_value: self._editor.verticalScrollBar().setValue(scroll_value + los) else: self._editor.verticalScrollBar().setValue(scroll_value - los) def __line_from_position(self, point): position = self.SendScintilla(QsciScintilla.SCI_POSITIONFROMPOINT, point.x(), point.y()) return self.SendScintilla(QsciScintilla.SCI_LINEFROMPOSITION, position) def enterEvent(self, event): if ACTIVATE_OPACITY: self.animation.setStartValue(settings.MINIMAP_MIN_OPACITY) self.animation.setEndValue(settings.MINIMAP_MAX_OPACITY) self.animation.start() def leaveEvent(self, event): if ACTIVATE_OPACITY: self.animation.setStartValue(settings.MINIMAP_MAX_OPACITY) self.animation.setEndValue(settings.MINIMAP_MIN_OPACITY) self.animation.start() def wheelEvent(self, event): super(MiniMap, self).wheelEvent(event) self._editor.wheelEvent(event) def resizeEvent(self, event): super(MiniMap, self).resizeEvent(event) self.slider.update_position()
class CImprovedButton(QToolButton): def __init__(self, parent=None): QToolButton.__init__(self, parent) #TESTO ALTERNATIVO #Spesso se il pulsante ha icona troppo grossa e quando per ragioni di spazio o altro non si può spostare #o ridimensionare il pulsante stesso, la label ha posizioni assurde e schifose. Aggiungerne una "+ controllabile" #è l'unico modo.. self.__fixed_label = QLabel("alternative label", self) self.__fixed_label.move(0, self.geometry().height() - 35) self.__fixed_label.resize(self.geometry().width(), self.__fixed_label.geometry().height()) self.__fixed_label.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) self.__font = QtGui.QFont("Arial", 10) self.__fixed_label.setFont(self.__font) self.__fixed_label.show() #INDICATORE STILE iOS self.__indicator = QLabel("0", self) self.__indicator.setStyleSheet( "border-image: url(':/images/backgrounds/indicator.png'); padding-right:1px; color: white;" ) self.__indicator.geometry().setWidth(25) self.__indicator.geometry().setHeight(20) self.__indicator.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter) self.__indicator.setVisible(False) self.setIndicatorPos(QPoint(self.width() - self.__indicator.width(), 0)) #default top-right corner #Quando il pulsante viene ridimensionato (designer o meno) devo anche sistemare la label di conseguenza self.resizeEvent = self.__onResize self.__indicator.resizeEvent = self.__on_indicator_Resize self.setToolButtonStyle(QtCore.Qt.ToolButtonIconOnly) self.clicked.connect(self.stopAllAnimations) #BLINK self.__blink_timer = QTimer(parent) self.__blink_timer.timeout.connect(self.__on_blink_timer) self.__blink_timer_interval = 1000 #FADING self.__opacity_effect = QGraphicsOpacityEffect() self.__fading_timer = QTimer(parent) self.__fading_timer.timeout.connect(self.__on_fading_timer) self.__FADE_TYPE = Enum("IN", "OUT") self.__fade_time = 20 self.__opacity = 1.0 self.__opacity_fading_coefficient = 0.02 self.__selected_fade_type = self.__FADE_TYPE.IN # ANIMAZIONI GROW self.__animationGrow = QPropertyAnimation(self, "iconSize", self) self.__animationGrow.setDuration(1000) self.__animationGrow.setEasingCurve(QEasingCurve.Linear) self.__animationGrow.finished.connect(self.__on_growed) self.__animationShrink = QPropertyAnimation(self, "iconSize", self) self.__animationShrink.setDuration(1000) self.__animationShrink.setEasingCurve(QEasingCurve.Linear) self.__animationShrink.finished.connect(self.__on_shrinked) self.__defaultIconDimension = 60 self.__iconGrowsBy = 40 self.__growing = False # ANIMAZIONI BOUNCE self.__animationUp = QPropertyAnimation(self, "pos", self) self.__animationUp.setDuration(200) self.__animationUp.setEasingCurve(QEasingCurve.Linear) self.__animationUp.finished.connect(self.__on_top_reached) self.__animationBounce = QPropertyAnimation(self, "pos", self) self.__animationBounce.setDuration(1000) self.__animationBounce.setEasingCurve(QEasingCurve.OutBounce) self.__animationBounce.finished.connect(self.__on_bounce_finished) self.__bouncing = False self.__startPos = QPoint(self.pos().x(), self.pos().y()) #PIXMAP & MASCHERA self.__pmap = QPixmap(self.size()) self.__pmap_fname = "" self.__show_mask_preview = False def setDefaultIconSize(self, value): """ Sets default icon size when growing stops. @param value: size (both width and height) @type value: int """ self.__defaultIconDimension = value def getDefaultIconSize(self): return self.__defaultIconDimension defaultIconSize = QtCore.pyqtProperty("int", getDefaultIconSize, setDefaultIconSize) def setFixetTextVisibility(self, bool): """ Sets if fixed text is visible or not. @param bool: visible or not @type bool: bool """ self.__fixed_label.setVisible(bool) def getFixetTextVisibility(self): return self.__fixed_label.isVisible() fixetTextVisibility = QtCore.pyqtProperty("bool", fget=getFixetTextVisibility, fset=setFixetTextVisibility) def setFixedText(self, txt): """ Sets text on the button. @param txt: text @type txt: string """ self.__fixed_label.setText(txt) def getFixedText(self): return self.__fixed_label.text() fixedText = QtCore.pyqtProperty("QString", getFixedText, setFixedText) def setFixedTextPos(self, qpoint): """ Sets text position in the button. @param qpoint: Position RELATIVE. 0,0 is top left corner of the button. @type qpoint: QPoint """ self.__fixed_label.move(qpoint) def getFixedTextPos(self): return self.__fixed_label.pos() fixedTextPos = QtCore.pyqtProperty("QPoint", getFixedTextPos, setFixedTextPos) def setFixedTextFont(self, font): """ Sets text font. @param font: Font for fixed text. @type font: QFont """ self.__font = font self.__fixed_label.setFont(self.__font) def getFixedTextFont(self): return self.__font fixedTextFont = QtCore.pyqtProperty("QFont", getFixedTextFont, setFixedTextFont) #FUNZIONI INDICATORE def setIndicatorVisibility(self, bool): """ Sets if indicator is visible or not. @param bool: visible or not @type bool: bool """ self.__indicator.setVisible(bool) def getIndicatorVisibility(self): return self.__indicator.isVisible() indicatorVisibility = QtCore.pyqtProperty("bool", fget=getIndicatorVisibility, fset=setIndicatorVisibility) def setIndicatorPos(self, qpoint): """ Sets indicator position in the button. @param qpoint: Position RELATIVE. 0,0 is top left corner of the button. @type qpoint: QPoint """ self.__indicator.move(qpoint) def getIndicatorPos(self): return self.__indicator.pos() indicatorPos = QtCore.pyqtProperty("QPoint", getIndicatorPos, setIndicatorPos) def setIndicatorSize(self, size): """ Sets indicator size. @param size: Size @type size: QSize """ self.__indicator.resize(size) def getIndicatorSize(self): return self.__indicator.size() indicatorSize = QtCore.pyqtProperty("QSize", getIndicatorSize, setIndicatorSize) def setIndicatorFont(self, font): """ Sets indicator text font. @param font: Font for indicator text. @type font: QFont """ self.__indicator.setFont(font) def getIndicatorFont(self): return self.__indicator.font() indicatorFont = QtCore.pyqtProperty("QFont", getIndicatorFont, setIndicatorFont) ## FUNZIONI PER BLINK def __on_blink_timer(self): self.setVisible(not (self.isVisible())) def setBlinking(self, blink): """ Sets if the button have to blink or not. @param blink: blinking or not @type blink: bool """ if blink: self.__blink_timer.setInterval(self.__blink_timer_interval) self.__blink_timer.start() else: self.__blink_timer.stop() self.setVisible(True) def setBlinkInterval(self, value): """ Sets blink interval. @param blink: blink interval (msec) @type blink: int """ self.__blink_timer_interval = value def getBlinkInterval(self): return self.__blink_timer_interval blinkInterval = QtCore.pyqtProperty("int", getBlinkInterval, setBlinkInterval) ##FUNZIONI PER FADING def fadeIn(self): """ Button fades in from completely invisible to completely visible. """ self.__opacity = 0.0 self.__selected_fade_type = self.__FADE_TYPE.IN self.__fading_timer.start(self.__fade_time) def fadeOut(self): """ Button fades out from completely visible to completely invisible. """ self.__selected_fade_type = self.__FADE_TYPE.OUT self.__fading_timer.start(self.__fade_time) def setFadeTime(self, value): """ Sets fading time. Everytime interval is reached, alpha is increased (or decreased) by __opacity_fading_coefficient. @param value: fade time (msec) @type value: int """ self.__fade_time = value def getFadeTime(self): return self.__fade_time fadeInterval = QtCore.pyqtProperty("int", getFadeTime, setFadeTime) def setFadeCoefficient(self, value): """ Sets fading coefficient. Alpha is increased (or decreased) by this value. @param value: coefficient (min 0.0 - max 1.0) @type value: float """ self.__opacity_fading_coefficient = value def getFadeCoefficient(self): return self.__opacity_fading_coefficient fadeCoefficient = QtCore.pyqtProperty("double", getFadeCoefficient, setFadeCoefficient) def __on_fading_timer(self): if self.__selected_fade_type == self.__FADE_TYPE.OUT: if self.__opacity > 0: self.__opacity -= self.__opacity_fading_coefficient self.__opacity_effect.setOpacity(self.__opacity) self.setGraphicsEffect(self.__opacity_effect) else: self.__fading_timer.stop() if self.__selected_fade_type == self.__FADE_TYPE.IN: if self.__opacity <= 1.0: self.__opacity += self.__opacity_fading_coefficient self.__opacity_effect.setOpacity(self.__opacity) self.setGraphicsEffect(self.__opacity_effect) else: self.__fading_timer.stop() # FUNZIONI PER GROW\SHRINK def __on_growed(self): self.__animationShrink.setStartValue( QSize(self.iconSize().width(), self.iconSize().height())) self.__animationShrink.setEndValue( QSize(self.iconSize().width() - self.__iconGrowsBy, self.iconSize().height() - self.__iconGrowsBy)) self.__animationShrink.start() def __on_shrinked(self): self.__animationGrow.setStartValue( QSize(self.iconSize().width(), self.iconSize().height())) self.__animationGrow.setEndValue( QSize(self.iconSize().width() + self.__iconGrowsBy, self.iconSize().height() + self.__iconGrowsBy)) self.__animationGrow.start() def startGrow(self): """ Button ICON starts to grow and shrink to standard value when maximum size (configured) is reached """ if self.__growing: return self.__animationGrow.setStartValue( QSize(self.iconSize().width(), self.iconSize().height())) self.__animationGrow.setEndValue( QSize(self.iconSize().width() + self.__iconGrowsBy, self.iconSize().height() + self.__iconGrowsBy)) self.__animationGrow.start() self.__growing = True def stopGrow(self): if self.__animationGrow.startValue().toSize() != QSize( 0, 0) and self.__animationShrink.startValue().toSize() != QPoint( 0, 0): self.__animationGrow.stop() self.__animationShrink.stop() self.setIconSize( QSize(self.__defaultIconDimension, self.__defaultIconDimension)) self.__growing = False #FUNZIONI PER BOUNCE def startBounce(self): """ Button starts to bounce requiring attention. """ if self.__bouncing: return self.__startPos = QPoint(self.pos().x(), self.pos().y()) self.__animationUp.setStartValue( QPoint(self.__startPos.x(), self.__startPos.y())) self.__animationUp.setEndValue( QPoint(self.__startPos.x(), self.__startPos.y() - self.geometry().height())) self.__animationUp.start() self.__bouncing = True def stopBounce(self): if self.__animationUp.startValue().toPoint() != QPoint( 0, 0) and self.__animationBounce.startValue().toPoint() != QPoint( 0, 0): self.__animationBounce.stop() self.__animationUp.stop() self.setGeometry(self.__startPos.x(), self.__startPos.y(), self.geometry().width(), self.geometry().height()) self.__bouncing = False def __on_top_reached(self): self.__animationBounce.setStartValue( QPoint(self.pos().x(), self.pos().y())) self.__animationBounce.setEndValue( QPoint(self.__startPos.x(), self.__startPos.y())) self.__animationBounce.start() def __on_bounce_finished(self): self.__animationUp.start() def stopAllAnimations(self): self.stopBounce() self.stopGrow() #FUNZIONI PER PIXMAP & MASCHERA def setPixmapFile(self, image_file): self.__pmap = image_file self.__pmap.scaled(self.size()) #NB: Il pixmap deve essere BIANCO e NERO. Con heuristicMask il primo pixel in alto a sinistra (0,0) viene #usato per decidere il colore trasparente, tutto il resto è visibile. def getPixmapFile(self): return self.__pmap pixmapFile = QtCore.pyqtProperty("QPixmap", getPixmapFile, setPixmapFile) def applyMask(self, bool): self.__show_mask_preview = bool if bool: self.setMask( QBitmap(self.__pmap.createHeuristicMask().scaled(self.size()))) else: self.setMask(QBitmap()) def getMask(self): return self.__show_mask_preview appliedMask = QtCore.pyqtProperty("bool", fget=getMask, fset=applyMask) def __onResize(self, event): self.__fixed_label.move(0, self.geometry().height() - 35) self.__fixed_label.resize(self.geometry().width(), self.__fixed_label.geometry().height()) self.setIndicatorPos(QPoint(self.width() - self.__indicator.width(), 0)) self.__pmap.scaled(self.size()) if self.__show_mask_preview: self.setMask( QBitmap(self.__pmap.createHeuristicMask().scaled(self.size()))) def __on_indicator_Resize(self, event): self.setIndicatorPos(QPoint(self.width() - self.__indicator.width(), 0))
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.init(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()