def __updateOrdAbsPos(self): # FIXME : handle the case where size.height() < self.MARGIN size = self.size() self.max_ord_pos = QPoint(self.MARGIN, self.MARGIN) self.max_abs_pos = QPoint(size.width() - self.MARGIN, size.height() - self.MARGIN) self.zero_pos = QPoint(self.MARGIN, size.height() - self.MARGIN)
def __init__(self,parent=None): super(Winform,self).__init__(parent) self.setWindowTitle("绘制矩形图形例子") self.pix = QPixmap() self.lastPoint = QPoint() self.endPoint = QPoint() self.initUi()
def click(): window_name = get_window_name() query_value = get_query_value() automation_type = get_query_automation_type() widget = find_widget(window_name, query_value, automation_type) if widget is None: return {} if isinstance(widget, QWidget): clicker.click_on(widget) return get_widget_json(widget) if isinstance(widget, QQuickItem): pointf = widget.mapToScene(QPointF(0.0, 0.0)) x = pointf.x() y = pointf.y() x += qml_method_or_default(widget, "width", 0.0) / 2.0 y += qml_method_or_default(widget, "height", 0.0) / 2.0 window_name = get_window_name() root_widget = get_root_widget(window_name) point = QPoint(x,y) quick_widget = root_widget.childAt(point.x(), point.y()) clicker.click_on(quick_widget, point) return get_widget_json(widget) return {}
def dropEvent(self, event): if event.mimeData().hasText(): mime = event.mimeData() pieces = mime.text().split() position = event.pos() hotSpot = QPoint() hotSpotPos = mime.data('application/x-hotspot').split(' ') if len(hotSpotPos) == 2: hotSpot.setX(hotSpotPos[0].toInt()[0]) hotSpot.setY(hotSpotPos[1].toInt()[0]) for piece in pieces: newLabel = DragLabel(piece, self) newLabel.move(position - hotSpot) newLabel.show() position += QPoint(newLabel.width(), 0) if event.source() in self.children(): event.setDropAction(Qt.MoveAction) event.accept() else: event.acceptProposedAction() else: event.ignore()
class CanvasView(QtCanvasView): itemClickedSignal = pyqtSignal(QtCanvasItem) itemMovedSignal = pyqtSignal(QtCanvasItem) def __init__(self, arg1=None, arg2=None): if type(arg1)==QtCanvas: super(CanvasView, self).__init__(arg1, arg2) else: super(CanvasView, self).__init__(arg1) self.moving = QtCanvasItem(None) self.moving_start = QPoint() def contentsMousePressEvent(self, event): self.handleMouseClickEvent(event) def contentsMouseDoubleClickEvent(self, event): self.handleMouseClickEvent(event) def handleMouseClickEvent(self, event): p = self.inverseWorldMatrix().map(event.pos()) l = self.canvas().collisions(p) self.moving = QtCanvasItem(None) if (not l.isEmpty()): self.moving = l.first() self.moving_start = p self.itemClickedSignal.emit(self.moving) def contentsMouseMoveEvent(self, event): if (self.moving): p = self.inverseWorldMatrix().map(event.pos()) self.moving.moveBy(p.x() - self.moving_start.x(), p.y() - self.moving_start.y()) self.moving_start = p self.canvas().update() self.itemMovedSignal.emit(self.moving)
def __init__(self, parent, binpath): super().__init__(parent) sizePolicy = QSizePolicy() sizePolicy.setHorizontalPolicy(QSizePolicy.Maximum) sizePolicy.setVerticalPolicy(QSizePolicy.Maximum) #self.setSizePolicy(sizePolicy) self.setMouseTracking(True) self.on_selection = False self.selected = False self.c = Communicate() self.start_position = QPoint(0,0) self.last_position = QPoint(0,0) image = ( b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" b"\x00\x00\xFF\xFF\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00" b"\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00" b"\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00" b"\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00" b"\x00\x00\xFF\xFF\x00\x00\x00\x00\x00\x00\x00\x00\xFF\xFF\x00\x00" b"\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\xFF\xFF\x00\x00" b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00") im = QImage(image, 8,8, QImage.Format_RGB16) im = im.scaled(64,64) self.crop = QPixmap() self.crop.convertFromImage(im)
def snapToGrid(self, position): #Return position of closest grid point gridSizeX = 40 gridSizeY = 20 curPos = QPoint(position.x(), position.y()) gridPos = QPoint(round(curPos.x() / gridSizeX) * gridSizeX, round(curPos.y() / gridSizeY) * gridSizeY) return gridPos
def get_linear_gradient(self): fontHeight = self.fontMetrics().height() startPoint = QPoint(self.rect().x(), self.rect().y() + 0.5 * (self.rect().height() - fontHeight)) endPoint = QPoint(startPoint.x(), startPoint.y() + fontHeight) linear = QLinearGradient(startPoint, endPoint) colorCounts = len(self.colors) for i in range(colorCounts): linear.setColorAt(0.2 + i / colorCounts, self.colors[i]) return linear
def __init__(self,parent=None): super(Winform,self).__init__(parent) self.setWindowTitle("双缓冲绘图例子") self.pix = QPixmap() self.lastPoint = QPoint() self.endPoint = QPoint() # 辅助画布 self.tempPix = QPixmap() # 标志是否正在绘图 self.isDrawing = False self.initUi()
class Winform(QWidget): def __init__(self,parent=None): super(Winform,self).__init__(parent) self.setWindowTitle("双缓冲绘图例子") self.pix = QPixmap() self.lastPoint = QPoint() self.endPoint = QPoint() # 辅助画布 self.tempPix = QPixmap() # 标志是否正在绘图 self.isDrawing = False self.initUi() def initUi(self): #窗口大小设置为600*500 self.resize(600, 500); # 画布大小为400*400,背景为白色 self.pix = QPixmap(400, 400); self.pix.fill(Qt.white); def paintEvent(self,event): painter = QPainter(self) x = self.lastPoint.x() y = self.lastPoint.y() w = self.endPoint.x() - x h = self.endPoint.y() - y # 如果正在绘图,就在辅助画布上绘制 if self.isDrawing : # 将以前pix中的内容复制到tempPix中,保证以前的内容不消失 self.tempPix = self.pix pp = QPainter( self.tempPix) pp.drawRect(x,y,w,h) painter.drawPixmap(0, 0, self.tempPix) else : pp = QPainter(self.pix ) pp.drawRect(x, y, w, h) painter.drawPixmap(0, 0, self.pix) def mousePressEvent(self, event) : # 鼠标左键按下 if event.button() == Qt.LeftButton : self.lastPoint = event.pos() self.endPoint = self.lastPoint self.isDrawing = True def mouseReleaseEvent( self, event): # 鼠标左键释放 if event.button() == Qt.LeftButton : self.endPoint = event.pos() #进行重新绘制 self.update() self.isDrawing = False
class Bullet: """Bullet contains: 1 StartPosition 2 EndPosition 3 Color 4 Text( A String) 5 Duration It uses the "window" to draw it selft """ #这个叫做 类的属性 Count=0# 通过类名Bullet.bullet访问,就是一个静态变量 Height=GLOBAL.BULLETFONTSIZE+6 #一个Bullet占用的像素高度 def __init__(self, Text, Color,Duration): Bullet.Count+=1 #这个里面self给定的内容则只属于当前对象 self.Text=Text self.Color=Color self.Duration=Duration*1000 #单位是毫秒,输入的是秒 self.IsExpired=False """this method must be called when this bullet is ready to shoot at the first time """ def prepare(self): self.elapsedTimer=QElapsedTimer() self.elapsedTimer.start() #start time self.StartPosition=QPoint(GLOBAL.WINDOWWIDTH+random.randrange(200,500,20),\ (Bullet.Height+(Bullet.Count%(GLOBAL.WINDOWHEIGHT//Bullet.Height))*Bullet.Height)) self.EndPosition=QPoint(-2000 ,self.StartPosition.y()) """Draw this bullet at position x,y ,use painter Returns True indicates this bullet is out of screen """ def draw(self,painter): ratio=self.elapsedTimer.elapsed()/self.Duration if(ratio>0.9): self.IsExpired=True # pos=ratio*self.EndPosition+(1-ratio)*self.StartPosition pos=QPoint(ratio*self.EndPosition.x()+(1-ratio)*self.StartPosition.x(),self.StartPosition.y()) #这里需要插入绘制字体阴影的代码 # # font.setFixedPitch(True) # painter.setFont(font) painter.save() painter.drawText(pos+QPoint(2,2),self.Text) painter.setPen(QPen(self.Color)) painter.drawText(pos,self.Text) painter.restore() # def __del__(self): # Count-=1 # print ("刚刚自动Delete了一个bullet\n")
def setOffset(self, offset): # Clamp the offset within the offset bounds newOffset = QPoint(min(self.mOffsetBounds.right(), max(self.mOffsetBounds.left(), offset.x())), min(self.mOffsetBounds.bottom(), max(self.mOffsetBounds.top(), offset.y()))) if (self.mOffset != newOffset): xChanged = self.mOffset.x() != newOffset.x() yChanged = self.mOffset.y() != newOffset.y() self.mOffset = newOffset if (xChanged): self.offsetXChanged.emit(self.mOffset.x()) if (yChanged): self.offsetYChanged.emit(self.mOffset.y()) self.offsetChanged.emit(self.mOffset) self.update()
def __init__(self, navigationInterpreter, positionModel, BoxContr, widget): ''' Class which interacts directly with the image scene :param navigationInterpreter: :param positionModel: :param BoxContr: :param widget: The main widget ''' QObject.__init__(self) self.baseInterpret = navigationInterpreter self._posModel = positionModel self.rubberBand = RedRubberBand(QRubberBand.Rectangle, widget) self.boxController=BoxContr self.leftClickReleased.connect(BoxContr.addNewBox) self.rightClickReceived.connect(BoxContr.onChangedPos) #self.deleteSelectedItemsSignal.connect(BoxContr.deleteSelectedItems) self.origin = QPoint() self.originpos = object()
def invalidate(self): if self.width <= 0 or self.height <= 0: return ct = tileForCoordinate(self.latitude, self.longitude, self.zoom) tx = ct.x() ty = ct.y() # top-left corner of the center tile xp = int(self.width / 2 - (tx - math.floor(tx)) * TDIM) yp = int(self.height / 2 - (ty - math.floor(ty)) * TDIM) # first tile vertical and horizontal xa = (xp + TDIM - 1) / TDIM ya = (yp + TDIM - 1) / TDIM xs = int(tx) - xa ys = int(ty) - ya # offset for top-left tile self._offset = QPoint(xp - xa * TDIM, yp - ya * TDIM) # last tile vertical and horizontal xe = int(tx) + (self.width - xp - 1) / TDIM ye = int(ty) + (self.height - yp - 1) / TDIM # build a rect self._tilesRect = QRect(xs, ys, xe - xs + 1, ye - ys + 1) if self._url.isEmpty(): self.download() self.updated.emit(QRect(0, 0, self.width, self.height))
def __init__(self): self.black = QColor(0, 0, 0) self.colors = [QColor(255, 0, 0), QColor(0, 255, 0), QColor(0 ,0, 255),\ QColor(128, 0, 128), QColor(128, 128, 0)] super().__init__() self.setGeometry(100, 100, 900,500) self.setFixedSize(1000, 500) self.flag_rects = True self.pen = False hbox = QHBoxLayout() hbox.addStretch(1) self.b_stop_entering = QPushButton("Закончить ввод", self) self.b_stop_entering.clicked[bool].connect(self.stop_entering) hbox.addWidget(self.b_stop_entering) vbox = QVBoxLayout() vbox.addStretch(1) vbox.addLayout(hbox) self.setLayout(vbox) self.setWindowTitle("Map") self.qp = QPainter() self.vertexes = [] self.edges = [] self.previous_point = QPoint() self.countries = [] self.points_for_country = []
def __init__(self, vcs, parent=None): """ Constructor @param vcs reference to the vcs object @param parent parent widget (QWidget) """ super(SvnLogBrowserDialog, self).__init__(parent) self.setupUi(self) self.__position = QPoint() self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) self.filesTree.headerItem().setText(self.filesTree.columnCount(), "") self.filesTree.header().setSortIndicator(0, Qt.AscendingOrder) self.vcs = vcs self.__initData() self.fromDate.setDisplayFormat("yyyy-MM-dd") self.toDate.setDisplayFormat("yyyy-MM-dd") self.__resetUI() self.__messageRole = Qt.UserRole self.__changesRole = Qt.UserRole + 1 self.process = QProcess() self.process.finished.connect(self.__procFinished) self.process.readyReadStandardOutput.connect(self.__readStdout) self.process.readyReadStandardError.connect(self.__readStderr) self.rx_sep1 = QRegExp('\\-+\\s*') self.rx_sep2 = QRegExp('=+\\s*') self.rx_rev1 = QRegExp( 'rev ([0-9]+): ([^|]*) \| ([^|]*) \| ([0-9]+) .*') # "rev" followed by one or more decimals followed by a colon followed # anything up to " | " (twice) followed by one or more decimals # followed by anything self.rx_rev2 = QRegExp( 'r([0-9]+) \| ([^|]*) \| ([^|]*) \| ([0-9]+) .*') # "r" followed by one or more decimals followed by " | " followed # anything up to " | " (twice) followed by one or more decimals # followed by anything self.rx_flags1 = QRegExp( r""" ([ADM])\s(.*)\s+\(\w+\s+(.*):([0-9]+)\)\s*""") # three blanks followed by A or D or M followed by path followed by # path copied from followed by copied from revision self.rx_flags2 = QRegExp(' ([ADM]) (.*)\\s*') # three blanks followed by A or D or M followed by path self.flags = { 'A': self.tr('Added'), 'D': self.tr('Deleted'), 'M': self.tr('Modified'), 'R': self.tr('Replaced'), } self.intercept = False
def mousePressEvent(self, ev): if ev.button() == Qt.LeftButton: self.info.close() self.setCursor(Qt.CrossCursor) self.start = QPoint(ev.pos()) self.rubberBand.setGeometry(QRect(self.start, QSize())) self.rubberBand.show()
def __init__(self, parent=None): super(GLWidget, self).__init__(parent) self.shapes = Shapes([]) self.orientation = 0 self.wpZero = 0 self.routearrows = [] self.expprv = None self.isPanning = False self.isRotating = False self.isMultiSelect = False self._lastPos = QPoint() self.posX = 0.0 self.posY = 0.0 self.posZ = 0.0 self.rotX = 0.0 self.rotY = 0.0 self.rotZ = 0.0 self.scale = 1.0 self.scaleCorr = 1.0 self.showPathDirections = False self.showDisabledPaths = False self.topLeft = Point() self.bottomRight = Point() self.tol = 0
def __init__(self, parent=None): super(GLWidget, self).__init__(parent) midnight = QTime(0, 0, 0) random.seed(midnight.secsTo(QTime.currentTime())) self.object = 0 self.xRot = 0 self.yRot = 0 self.zRot = 0 self.image = QImage() self.bubbles = [] self.lastPos = QPoint() self.trolltechGreen = QColor.fromCmykF(0.40, 0.0, 1.0, 0.0) self.trolltechPurple = QColor.fromCmykF(0.39, 0.39, 0.0, 0.0) self.animationTimer = QTimer() self.animationTimer.setSingleShot(False) self.animationTimer.timeout.connect(self.animate) self.animationTimer.start(25) self.setAutoFillBackground(False) self.setMinimumSize(200, 200) self.setWindowTitle("Overpainting a Scene")
def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self.origin = QPoint(event.pos()) self.rubberBand.setGeometry(QRect(self.origin, QSize())) self.rubberBand.show()
def __init__(self, parent=None): super(PWidgetGL, self).__init__(parent) self.object = 0 self.xRot = 500 self.yRot = 500 self.zRot = 0 self.coordLength = 3.0 self.lastPos = QPoint() self.rn = 0.0 self.Trn = 0.0 self.trolltechBlue = QColor.fromCmykF(1.0, 0.40, 0.0, 0.0) self.trolltechRed = QColor.fromCmykF(0.0, 1.0, 0.40, 0.0) self.trolltechGreen = QColor.fromCmykF(0.40, 0.0, 1.0, 0.0) self.trolltechBlack = QColor.fromCmykF(0.0, 0.0, 0.0, 1.0) self.timer = QTimer(self) self.timer.timeout.connect(self.animate) self.inited = False self.rcount = 0 self.tcount = 0 self.vcount = 0.0
def __init__(self, arg1=None, arg2=None): if type(arg1)==QtCanvas: super(CanvasView, self).__init__(arg1, arg2) else: super(CanvasView, self).__init__(arg1) self.moving = QtCanvasItem(None) self.moving_start = QPoint()
class Winform(QWidget): def __init__(self,parent=None): super(Winform,self).__init__(parent) self.setWindowTitle("绘制矩形图形例子") self.pix = QPixmap() self.lastPoint = QPoint() self.endPoint = QPoint() self.initUi() def initUi(self): #窗口大小设置为600*500 self.resize(600, 500) # 画布大小为400*400,背景为白色 self.pix = QPixmap(400, 400) self.pix.fill(Qt.white) def paintEvent(self,event): painter = QPainter(self) x = self.lastPoint.x() y = self.lastPoint.y() w = self.endPoint.x() - x h = self.endPoint.y() - y pp = QPainter(self.pix) pp.drawRect(x, y, w, h) painter.drawPixmap(0, 0, self.pix) def mousePressEvent(self, event) : # 鼠标左键按下 if event.button() == Qt.LeftButton : self.lastPoint = event.pos() self.endPoint = self.lastPoint def mouseMoveEvent(self, event): # 鼠标左键按下的同时移动鼠标 if event.buttons() and Qt.LeftButton : self.endPoint = event.pos() #进行重新绘制 self.update() def mouseReleaseEvent( self, event): # 鼠标左键释放 if event.button() == Qt.LeftButton : self.endPoint = event.pos() #进行重新绘制 self.update()
def tryMove(self, oldPos, newPos, directions): p = QPoint(oldPos) if directions & 1: #X轴方向 gridX = self.parent().width() / 40 delta = newPos.x() - oldPos.x() if abs(delta) / gridX > 0.5: newX = oldPos.x() + delta / abs(delta) * gridX * round(abs(delta) / gridX) newX = gridX * round(newX / gridX) p.setX(newX) if directions & 2: gridY = self.parent().height() / 30 delta = newPos.y() - oldPos.y() if abs(delta) / gridY > 0.5: newY = oldPos.y() + delta / abs(delta) * gridY * round(abs(delta) / gridY) newY = gridY * round(newY / gridY) p.setY(newY) return p
def mouseReleaseEvent(self, event): if event.button() == Qt.LeftButton: self.pixmapOffset += event.pos() - self.lastDragPos self.lastDragPos = QPoint() deltaX = (self.width() - self.pixmap.width()) / 2 - self.pixmapOffset.x() deltaY = (self.height() - self.pixmap.height()) / 2 - self.pixmapOffset.y() self.scroll(deltaX, deltaY)
def __init__(self, name, icon, shortcut, parent = None): super(AbstractTileTool, self).__init__(name, icon, shortcut, parent) self.mTilePositionMethod = TilePositionMethod.OnTiles self.mBrushItem = BrushItem() self.mBrushVisible = False self.mTilePosition = QPoint() self.mBrushItem.setVisible(False) self.mBrushItem.setZValue(10000)
def __init__(self, parent=None): super(MandelbrotWidget, self).__init__(parent) self.thread = RenderThread() self.pixmap = QPixmap() self.pixmapOffset = QPoint() self.lastDragPos = QPoint() self.centerX = DefaultCenterX self.centerY = DefaultCenterY self.pixmapScale = DefaultScale self.curScale = DefaultScale self.thread.renderedImage.connect(self.updatePixmap) self.setWindowTitle("Mandelbrot") self.setCursor(Qt.CrossCursor) self.resize(550, 400)
def updatePixmap(self, image, scaleFactor): if not self.lastDragPos.isNull(): return self.pixmap = QPixmap.fromImage(image) self.pixmapOffset = QPoint() self.lastDragPosition = QPoint() self.pixmapScale = scaleFactor self.update()
def __init__(self, parent = None, func=None): self.func = func QLabel.__init__(self, parent) self.rubberBand = QRubberBand(QRubberBand.Rectangle, self) self.origin = QPoint() self.slitpos = 250 self.focus = (333,666,333,666) #xs,xe,ys,ye self.geometry = (0,0,1000,1000) #x,y,w,h
def draw_line_to(self, end_point): painter = QPainter(self.image) painter.setPen(QPen(self.foreground_color if self.scribbling == 1 else self.background_color, self.pen_width, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin)) painter.drawLine(QPoint(self.last_point.x()//self.scaling_factor, self.last_point.y()//self.scaling_factor), QPoint(end_point.x()//self.scaling_factor, end_point.y()//self.scaling_factor)) self.update() self.last_point = QPoint(end_point)
def __init__(self): super().__init__() top = 400 #задаём размеры окна left = 400 width = 800 height = 600 icon = 'icons/paint.png' self.setWindowTitle('Paint Application') self.setGeometry(top, left, width, height) self.setWindowIcon(QIcon(icon)) self.image = QImage(self.size(), QImage.Format_RGB32) self.image.fill(Qt.white) self.drawing = False self.brushSize = 2 self.brushColor = Qt.black self.lastPoint = QPoint() mainMenu = self.menuBar() #создаём кнопки для выбора цвета, размера кисти, сохранения файла и очищения холста fileMenu = mainMenu.addMenu('Файл') brushMenu = mainMenu.addMenu('Размер') brushColor = mainMenu.addMenu('Цвет') saveAction = QAction(QIcon('icons/save.png'), 'Сохранить', self) saveAction.setShortcut('Ctrl+S') fileMenu.addAction(saveAction) saveAction.triggered.connect(self.save) clearAction = QAction(QIcon('icons/clear.png'), 'Очистить', self) clearAction.setShortcut('Ctrl+C') fileMenu.addAction(clearAction) clearAction.triggered.connect(self.clear) threepxAction = QAction(QIcon('icons/threepx.png'), '3px', self) threepxAction.setShortcut('Ctrl+T') brushMenu.addAction(threepxAction) threepxAction.triggered.connect(self.threePx) fivepxAction = QAction(QIcon('icons/fivepx.png'), '5px', self) fivepxAction.setShortcut('Ctrl+F') brushMenu.addAction(fivepxAction) fivepxAction.triggered.connect(self.fivePx) sevenpxAction = QAction(QIcon('icons/sevenpx.png'), '7px', self) sevenpxAction.setShortcut('Ctrl+S') brushMenu.addAction(sevenpxAction) sevenpxAction.triggered.connect(self.sevenPx) ninepxAction = QAction(QIcon('icons/ninepx.png'), '9px', self) ninepxAction.setShortcut('Ctrl+N') brushMenu.addAction(ninepxAction) ninepxAction.triggered.connect(self.ninePx) blackAction = QAction(QIcon('icons/black.png'), 'Черный', self) blackAction.setShortcut('Ctrl + B') brushColor.addAction(blackAction) blackAction.triggered.connect(self.blackColor) redAction = QAction(QIcon('icons/red.png'), 'Красный', self) redAction.setShortcut('Ctrl + W') brushColor.addAction(redAction) redAction.triggered.connect(self.redColor) greenAction = QAction(QIcon('icons/green.png'), 'Зеленый', self) greenAction.setShortcut('Ctrl + G') brushColor.addAction(greenAction) greenAction.triggered.connect(self.greenColor) yellowAction = QAction(QIcon('icons/yellow.png'), 'Желтый', self) yellowAction.setShortcut('Ctrl + H') brushColor.addAction(yellowAction) yellowAction.triggered.connect(self.yellowColor) whiteAction = QAction(QIcon('icons/white.png'), 'Ластик', self) whiteAction.setShortcut('Ctrl + J') brushColor.addAction(whiteAction) whiteAction.triggered.connect(self.whiteColor)
def updatePaintNode(self, paint_node, update_data): if paint_node is None: paint_node = QSGGeometryNode() geometry = QSGGeometry(QSGGeometry.defaultAttributes_Point2D(), 7, 9) geometry.setDrawingMode(QSGGeometry.GL_TRIANGLES) geometry.vertexDataAsPoint2D()[0].set(0, 0) geometry.vertexDataAsPoint2D()[1].set(0, self.height()) geometry.vertexDataAsPoint2D()[2].set(self.width(), self.height()) geometry.vertexDataAsPoint2D()[3].set(self.width(), 0) # no arrow by default geometry.vertexDataAsPoint2D()[4].set(0, 0) geometry.vertexDataAsPoint2D()[5].set(0, 0) geometry.vertexDataAsPoint2D()[6].set(0, 0) target_offset = self._target - QPoint(self.x(), self.y()) if target_offset.x() >= 0 and target_offset.x() <= self.width(): arrow_size = min(self._arrow_size, self.width() / 2) arrow_offset = max( arrow_size, min(self.width() - arrow_size, target_offset.x())) if target_offset.y() < 0: # top geometry.vertexDataAsPoint2D()[4].set( arrow_offset - arrow_size, 0) geometry.vertexDataAsPoint2D()[5].set(arrow_offset, -arrow_size) geometry.vertexDataAsPoint2D()[6].set( arrow_offset + arrow_size, 0) elif target_offset.y() > self.height(): # bottom geometry.vertexDataAsPoint2D()[4].set( arrow_offset - arrow_size, self.height()) geometry.vertexDataAsPoint2D()[5].set( arrow_offset, self.height() + arrow_size) geometry.vertexDataAsPoint2D()[6].set( arrow_offset + arrow_size, self.height()) elif target_offset.y() >= 0 and target_offset.y() <= self.height(): arrow_size = min(self._arrow_size, self.height() / 2) arrow_offset = max( arrow_size, min(self.height() - arrow_size, target_offset.y())) if target_offset.x() < 0: # left geometry.vertexDataAsPoint2D()[4].set( 0, arrow_offset - arrow_size) geometry.vertexDataAsPoint2D()[5].set(-arrow_size, arrow_offset) geometry.vertexDataAsPoint2D()[6].set( 0, arrow_offset + arrow_size) elif target_offset.x() > self.width(): # right geometry.vertexDataAsPoint2D()[4].set( self.width(), arrow_offset - arrow_size) geometry.vertexDataAsPoint2D()[5].set( self.width() + arrow_size, arrow_offset) geometry.vertexDataAsPoint2D()[6].set( self.width(), arrow_offset + arrow_size) geometry.indexDataAsUShort()[0] = 0 geometry.indexDataAsUShort()[1] = 1 geometry.indexDataAsUShort()[2] = 2 geometry.indexDataAsUShort()[3] = 0 geometry.indexDataAsUShort()[4] = 2 geometry.indexDataAsUShort()[5] = 3 geometry.indexDataAsUShort()[6] = 4 geometry.indexDataAsUShort()[7] = 5 geometry.indexDataAsUShort()[8] = 6 paint_node.setGeometry(geometry) material = QSGFlatColorMaterial() material.setColor(self._color) paint_node.setMaterial(material) # For PyQt 5.4, I need to store these otherwise they will be garbage collected before rendering # and never show up, but otherwise never crash. self._paint_node = paint_node self._geometry = geometry self._material = material return paint_node
def update_image(self, pixmap): self.imgPixmap = pixmap self.scaledImg = self.imgPixmap.copy() self.img_offset = QPoint(0, 0) self.update() # repaint the image
def mouseMoveEvent(self, event): delta = QPoint (event.globalPos() - self.oldPos) self.move(self.x() + delta.x(), self.y() + delta.y()) self.oldPos = event.globalPos()
def paintEvent(self, e): self.painter.begin(self) # 绘制图片内容 self.painter.drawPixmap(self.rect(), self.pixmap, self.pmapShowAreaRect) # 绘制图片区域预览 self.painter.setPen(QColor(0, 0, 0)) scale = min(self.width() / self.pixmap.width() / 5, self.height() / self.pixmap.height() / 5) self.pmapPreRect = QRect(0, 0, self.pixmap.width() * scale, self.pixmap.height() * scale) margin = int(min(self.width(), self.height()) / 16) self.pmapPreRect.moveTopRight(QPoint(self.width() - margin, margin)) self.painter.drawRect(self.pmapPreRect) # 绘制图片展示区域预览 self.painter.setPen(QColor(255, 0, 0)) pmapprerect = self.pmapPreRect.getRect() pmapshowarearect = self.pmapShowAreaRect.getRect() x = pmapprerect[0] + self.pmapPreRect.width( ) * pmapshowarearect[0] / self.pixmap.width() y = pmapprerect[1] + self.pmapPreRect.height( ) * pmapshowarearect[1] / self.pixmap.height() w = scale * self.pmapShowAreaRect.width() h = scale * self.pmapShowAreaRect.height() self.pmapShowAreaPreRect = QRect(x, y, w, h) self.painter.drawRect(self.pmapShowAreaPreRect) self.dragAreaRect = QRect( self.pmapPreRect.x() - self.pmapShowAreaPreRect.width(), self.pmapPreRect.y() - self.pmapShowAreaPreRect.height(), self.pmapShowAreaPreRect.width() + self.pmapPreRect.width(), self.pmapShowAreaPreRect.height() + self.pmapPreRect.height()) # 绘制缩放中心点标线 self.painter.setPen(QColor(255, 0, 0)) self.painter.drawLine(self.width() / 3, self.height() / 2, self.width() / 3 * 2, self.height() / 2) self.painter.drawLine(self.width() / 2, self.height() / 3, self.width() / 2, self.height() / 3 * 2) # 绘制鼠标位置标线 if self.labeling: self.painter.setPen(QColor(0, 0, 0)) self.painter.drawLine(self.mousex, 0, self.mousex, self.height()) self.painter.drawLine(0, self.mousey, self.width(), self.mousey) # 绘制正在编辑中的label位置 if self.templabel: for i in range(int(len(self.templabel) / 2)): imagex, imagey = self.templabel[0 + 2 * i], self.templabel[1 + 2 * i] if self.pmapShowAreaRect.contains(imagex, imagey): widgetx, widgety = self.imageXY2WidgetXY(imagex, imagey) self.painter.setPen(QPen(Qt.red, 5)) self.painter.drawPoint(widgetx, widgety) pen = QPen(Qt.black, 2, Qt.SolidLine) pen.setStyle(Qt.DashDotDotLine) self.painter.setPen(pen) self.painter.drawLine(widgetx, 0, widgetx, self.height()) self.painter.drawLine(0, widgety, self.width(), widgety) # 绘制已标记内容 self.deleteRects.clear() self.textRects.clear() self.painter.setPen(QColor(168, 34, 3)) self.painter.setFont(QFont('Decorative', 12)) metrics = self.painter.fontMetrics() deleteRectWidth, deleteRectHeight = metrics.height( ) * 1.2, metrics.height() * 1.2 separatorheight = margin / 10 pmapprerect = self.pmapPreRect.getRect() topRightx, topRighty = self.width( ) - margin, pmapprerect[1] + pmapprerect[3] + margin / 4 for i in range(len(self.labels)): label = self.labels[i] # 绘制文字展示信息 text = label[4] deleteRect = QRect( topRightx - deleteRectWidth, topRighty + (deleteRectHeight + separatorheight) * i, deleteRectWidth, deleteRectHeight) self.painter.drawRect(deleteRect) self.painter.drawLine(deleteRect.topLeft(), deleteRect.bottomRight()) self.painter.drawLine(deleteRect.topRight(), deleteRect.bottomLeft()) self.deleteRects.append(deleteRect) deleterect = deleteRect.getRect() textWidth, textHeight = metrics.width(text), metrics.height() textRect = QRect(deleterect[0] - textWidth - metrics.height(), deleterect[1], textWidth + metrics.height(), deleterect[3]) self.painter.drawRect(textRect) self.painter.drawText(textRect, Qt.AlignCenter, text) self.textRects.append(textRect) # 在图片上绘制标签矩形框 labelPixmapX, labelPixmapY, labelPixmapWidth, labelPixmapHeight = label[: 4] labelPixmapRect = QRect(labelPixmapX, labelPixmapY, labelPixmapWidth, labelPixmapHeight) intersectedRect = self.pmapShowAreaRect.intersected( labelPixmapRect) if intersectedRect: pixmapTopLeftPoint, pixmapBottomRightPoint = intersectedRect.topLeft( ), intersectedRect.bottomRight() widgetTopLeftPointX, widgetTopLeftPointY = self.imageXY2WidgetXY( pixmapTopLeftPoint.x(), pixmapTopLeftPoint.y()) widgetTopLeftPoint = QPoint(widgetTopLeftPointX, widgetTopLeftPointY) widgetBottomRightPointX, widgetBottomRightPointY = self.imageXY2WidgetXY( pixmapBottomRightPoint.x(), pixmapBottomRightPoint.y()) widgetBottomRightPoint = QPoint(widgetBottomRightPointX, widgetBottomRightPointY) labelRect = QRect(widgetTopLeftPoint, widgetBottomRightPoint) self.painter.drawRect(labelRect) # 绘制标签名 labelrect = labelRect.getRect() textRect1 = QRect(labelrect[0], labelrect[1] - textHeight, textWidth, textHeight) # self.painter.drawRect(textRect1) self.painter.drawText(textRect1, Qt.AlignCenter, text) self.painter.end()
def sheet2view(self, cord): #Get spritesheet position relative to mouse position return QPoint(math.floor((cord.x() - self.camera.x()) * self.scale), math.floor((cord.y() - self.camera.y()) * self.scale))
def view2sheet(self, cord): #Get mouse position relative to the spritesheet return QPoint(math.floor(cord.x() / self.scale) + self.camera.x(), math.floor(cord.y() / self.scale) + self.camera.y())
def mouseMoveEvent(self, mouse): self.last_mouse_pos = mouse.pos() if self.isPanning: # Move spritesheet frame according to mouse displacement mouse_pos_change = (mouse.pos() - self.mouse_press_pos) / self.scale self.camera = self.camera_old - mouse_pos_change self.constrain_camera() self.calc_sizing_handles() # Creating a new frame if self.mode == ViewerMode.NEW_FRAME: if self.left_mouse_down: # Adjust size of new frame selection clicked_pos = self.view2sheet(self.mouse_press_pos) mouse_pos = self.view2sheet(mouse.pos()) frame = self.animation_data.active_frame frame.setTopLeft(clicked_pos) frame.setBottomRight(QPoint(mouse_pos.x()-1, mouse_pos.y()-1)) self.animation_data_changed_signal.emit() # Altering an existing frame elif self.mode == ViewerMode.ALTER_SELECTION: if self.animation_data.active_frame is not None and self.animation_data.active_frame in self.animation_data.active_sequence.selected: a_frame = self.animation_data.active_frame mouse_rel = self.view2sheet(mouse.pos()) if self.sizing_mode is None: # self.sizing_handles -> contains 8 rects self.setCursor(Qt.ArrowCursor) if a_frame.contains(mouse_rel): self.setCursor(self.move_frame_cursor) for i in range(0, len(self.sizing_handles)): if self.sizing_handles[i].contains(mouse.pos()): self.setCursor(self.sizing_handle_cursors[i]) elif self.left_mouse_down: # Position = original + (mouse_click_pos - mouse_current_pos) delta_mouse = self.view2sheet(self.mouse_press_pos) - self.view2sheet(mouse.pos()) if self.sizing_mode is SizingMode.MOVE_FRAME: selected_frames = self.animation_data.selected_frames() i = 0 for frame in self.original_frame_positions: selected_frames[i].moveTo(frame.topLeft() - delta_mouse) i += 1 elif self.sizing_mode is SizingMode.TOP_LEFT: a_frame.setTopLeft(self.original_frame.topLeft() - delta_mouse) elif self.sizing_mode is SizingMode.TOP: a_frame.setTop(self.original_frame.top() - delta_mouse.y()) elif self.sizing_mode is SizingMode.TOP_RIGHT: a_frame.setTopRight(self.original_frame.topRight() - delta_mouse) elif self.sizing_mode is SizingMode.RIGHT: a_frame.setRight(self.original_frame.right() - delta_mouse.x()) elif self.sizing_mode is SizingMode.BOTTOM_RIGHT: a_frame.setBottomRight(self.original_frame.bottomRight() - delta_mouse) elif self.sizing_mode is SizingMode.BOTTOM: a_frame.setBottom(self.original_frame.bottom() - delta_mouse.y()) elif self.sizing_mode is SizingMode.BOTTOM_LEFT: a_frame.setBottomLeft(self.original_frame.bottomLeft() - delta_mouse) elif self.sizing_mode is SizingMode.LEFT: a_frame.setLeft(self.original_frame.left() - delta_mouse.x()) self.animation_data_changed_signal.emit() self.calc_sizing_handles() self.update()
def center_camera(self, point: QPoint) -> None: """ Centers the camera on a point on the spritesheet""" self.camera = QPoint(point.x() - self.width()/(2*self.scale), point.y() - self.height()/(2*self.scale)) self.constrain_camera()
def position(self, x, y): return QPoint(x, y)
def snap_to_pixels(self, cord): return QPoint(cord.x() - cord.x() % self.scale, cord.y() - cord.y() % self.scale)
class SpritesheetViewer(QtWidgets.QFrame): left_mouse_down = False mouse_press_pos = None last_mouse_pos = QPoint(0, 0) spritesheet_image = None animation_data = None bg_image = None bg_tile_num = (120, 108) bg_tile_size = 10 SCALE_DELTA = 1 SCALE_MAX = 10 SCALE_MIN = 1 SCALE_DEFAULT = 1 BOX_SIZE = 10 isPanning = False camera = QPoint(0, 0) sheet_margin = QSize(10, 10) mode = None sizing_handles = None sizing_mode = None scale_changed_signal = pyqtSignal(float) animation_data_changed_signal = pyqtSignal() sizing_handle_cursors = [ Qt.SizeFDiagCursor, Qt.SizeVerCursor, Qt.SizeBDiagCursor, Qt.SizeHorCursor, Qt.SizeFDiagCursor, Qt.SizeVerCursor, Qt.SizeBDiagCursor, Qt.SizeHorCursor ] move_frame_cursor = Qt.SizeAllCursor def __init__(self, parent=None): super(SpritesheetViewer, self).__init__() self.setParent(parent) self.draw_bg_image() self.update() self.show() self.zoom_cursor = QtGui.QCursor(QtGui.QPixmap("icons/zoom.png")) self.zoom_in_cursor = QtGui.QCursor(QtGui.QPixmap("icons/zoom_in.png")) self.zoom_out_cursor = QtGui.QCursor(QtGui.QPixmap("icons/zoom_out.png")) self.scale_label = QtWidgets.QLabel("") self.setMouseTracking(True) self.setFocusPolicy(Qt.ClickFocus) self._scale = self.SCALE_DEFAULT self.original_frame_positions = [] def load_animation_data(self, animation_data): self.animation_data = animation_data self.animation_data.active_sequence_changed.connect(self.handle_sequence_signal) self.animation_data.active_frame_changed.connect(self.handle_frame_signal) self.reset_spritesheet() def renew(self): if self.animation_data is None: return self.calc_sizing_handles() self.update() def reset_spritesheet(self): self.scale = self.SCALE_DEFAULT self.spritesheet_image = QtGui.QImage(self.animation_data.spritesheet_path) self.center_sequence() self.update() @property def scale(self): return self._scale @scale.setter def scale(self, scale): # Get coordinates of mouse relative to viewer scale = max(round(scale, 1), self.SCALE_MIN) scale = min(round(scale, 1), self.SCALE_MAX) scale_diff = scale - self._scale old_camera_size = self.size() / self.scale new_camera_size = self.size() / (self.scale + scale_diff) size_ratio = new_camera_size.width() / old_camera_size.width() mouse = self.view2sheet(self.last_mouse_pos) mouse_ratio_x = (mouse.x() - self.camera.x()) / old_camera_size.width() mouse_ratio_y = (mouse.y() - self.camera.y()) / old_camera_size.height() camera_x = mouse.x() - (new_camera_size.width() * mouse_ratio_x) camera_y = mouse.y() - (new_camera_size.height() * mouse_ratio_y) self._scale = scale self.camera = QPoint(camera_x, camera_y) self.constrain_camera() self.calc_sizing_handles() self.update() self.scale_changed_signal.emit(scale) def draw_bg_image(self): # Prepare an image of background tiles self.bg_image = QtGui.QImage(self.bg_tile_num[0] * self.bg_tile_size, self.bg_tile_num[1] * self.bg_tile_size, QtGui.QImage.Format_Grayscale8) qp = QtGui.QPainter() qp.begin(self.bg_image) for x in range(0, self.bg_tile_num[0]): for y in range(0, self.bg_tile_num[1]): if ((y + x) % 2) == 1: qp.fillRect(x * self.bg_tile_size, y *self.bg_tile_size, self.bg_tile_size, self.bg_tile_size, QtGui.QColor(255, 255, 255)) else: qp.fillRect(x * self.bg_tile_size, y * self.bg_tile_size, self.bg_tile_size, self.bg_tile_size, QtGui.QColor(200, 200, 200)) qp.end() def zoom_in(self): self.scale = self.scale + self.SCALE_DELTA def zoom_out(self): self.scale = self.scale - self.SCALE_DELTA def handle_sequence_signal(self): self.center_sequence() def handle_frame_signal(self): self.calc_sizing_handles() """ EVENTS """ def paintEvent(self, event): qp = QtGui.QPainter() qp.begin(self) qp.setClipRect(0, 0, self.size().width(), self.size().height()) # BACKGROUND tiles if self.bg_image: qp.drawImage(0, 0, self.bg_image) # SPRITESHEET, cut and scaled cutout_size = (math.ceil(self.frameRect().width() / self.scale), math.ceil(self.frameRect().height() / self.scale)) if self.spritesheet_image: ss_cut = self.spritesheet_image.copy(self.camera.x(), self.camera.y(), cutout_size[0], cutout_size[1]) ss_cut = ss_cut.scaled(cutout_size[0] * self.scale, cutout_size[1] * self.scale) qp.drawImage(0, 0, ss_cut) # SELECTION BOXES around frames of sequence if self.animation_data and self.animation_data.active_sequence and self.animation_data.active_sequence.frames: self.draw_frames(qp) #draw MOUSE CROSSHAIR when creating new frames if self.mode == ViewerMode.NEW_FRAME: if self.last_mouse_pos is not None and self.underMouse(): self.draw_crosshair(qp) qp.end() def snap_to_pixels(self, cord): return QPoint(cord.x() - cord.x() % self.scale, cord.y() - cord.y() % self.scale) def draw_crosshair(self, qp): cord = self.snap_to_pixels(self.last_mouse_pos) qp.drawLine(cord.x(), 0, cord.x(), self.size().height()) qp.drawLine(0, cord.y(), self.size().width(), cord.y()) # Debug: draw dot where cursor actualy is qp.drawEllipse(self.last_mouse_pos, 1, 1) rCord = self.view2sheet(self.last_mouse_pos) qp.drawText(cord.x() + 2, cord.y() + 10, "X: %s Y: %s" % (cord.x(), cord.y())) qp.drawText(cord.x() + 2, cord.y() + 20, "rX: %s rY: %s" % (rCord.x(), rCord.y())) def draw_frames(self, qp): qp.setBackgroundMode(Qt.OpaqueMode) black_pen = QtGui.QPen(QtGui.QColor(0, 0, 0)) white_pen = QtGui.QPen(QtGui.QColor(255, 255, 255)) grey_pen = QtGui.QPen(QtGui.QColor("gray")) for sequence in self.animation_data.selected: i = 0 for frame in sequence.frames: # Draw frame border # REPEAT 1 pos = self.sheet2view(frame.topLeft()) size = QSize(round(frame.width() * self.scale), round(frame.height() * self.scale)) qp.setPen(white_pen) qp.setBackground(QtGui.QBrush(QtGui.QColor(0, 0, 0))) #qp.drawText(pos.x(), pos.y() - 2, "POS(%s, %s) SIZE(%s, %s)" % (frame.x(), frame.y(), frame.width(), frame.height())) qp.drawText(pos.x() + 1, pos.y() + 12, str(i)) qp.drawText( pos.x() + 1, pos.y() + size.height() + 12, "WIDTH: %s HEIGHT: %s" % (frame.width(), frame.height()) ) qp.setPen(black_pen) qp.setBackground(QtGui.QBrush(QtGui.QColor(255, 255, 255))) # Draw frame border qp.setBackgroundMode(Qt.TransparentMode) qp.drawRect(pos.x(), pos.y(), size.width(), size.height()) # Rect qp.setBackgroundMode(Qt.OpaqueMode) # Highlight the selected frames if self.mode == ViewerMode.ALTER_SELECTION: # REPEAT 3 a_pos = self.sheet2view(frame.topLeft()) a_size = QSize(round(frame.width() * self.scale), round(frame.height() * self.scale)) if frame in sequence.selected: if frame == sequence.active_frame: colour = QtGui.QColor(180, 215, 255, 100) qp.drawText(a_pos.x(), a_pos.y() - 10, "ACTIVE") else: colour = QtGui.QColor(255, 255, 0, 100) qp.drawText(a_pos.x(), a_pos.y() - 10, "SELECTED") qp.fillRect(a_pos.x() + 1, a_pos.y() + 1, a_size.width() - 1, a_size.height() - 1, colour) i += 1 if self.mode == ViewerMode.ALTER_SELECTION: a_frame = self.animation_data.active_frame mods = QtWidgets.QApplication.keyboardModifiers() if mods & Qt.ControlModifier: shift = self.sheet2view( QPoint( a_frame.x() + a_frame.shift.x(), a_frame.y() + a_frame.shift.y() ) ) circle_radius = 5 qp.drawEllipse( shift.x() - circle_radius, shift.y() - circle_radius, circle_radius * 2, circle_radius * 2 ) qp.drawLine( shift.x(), shift.y() + 4, shift.x(), shift.y() - 4 ) qp.drawLine( shift.x() + 4, shift.y(), shift.x() - 4, shift.y() ) else: self.draw_sizing_handles(qp) def calc_sizing_handles(self): if self.animation_data.active_frame is None: return active_frame = self.animation_data.active_frame pos = self.sheet2view(active_frame.topLeft()) size = active_frame.size() * self.scale box_size = self.BOX_SIZE self.sizing_handles = [ QRect(pos.x() - box_size/2, pos.y() - box_size/2, box_size, box_size), # Top Left QRect(pos.x() + size.width()/2 - box_size/2, pos.y() - box_size/2, box_size, box_size), # Top QRect(pos.x() + size.width() - box_size/2, pos.y() - box_size/2, box_size, box_size), # Top Right QRect(pos.x() + size.width() - box_size/2, pos.y() + size.height()/2 - box_size/2, box_size, box_size), # Right QRect(pos.x() + size.width() - box_size/2, pos.y() + size.height() - box_size/2, box_size, box_size), # Bottom Right QRect(pos.x() + size.width()/2 - box_size/2, pos.y() + size.height() - box_size/2, box_size, box_size), # Bottom QRect(pos.x() - box_size/2, pos.y() + size.height() - box_size/2, box_size, box_size), # Bottom Left QRect(pos.x() - box_size/2, pos.y() + size.height()/2 - box_size/2, box_size, box_size) # Left ] def draw_sizing_handles(self, qp): if self.sizing_handles is None: return if self.animation_data.active_frame is None or self.animation_data.active_frame not in self.animation_data.active_sequence.selected: return qp.setBrush(QtGui.QBrush(QtGui.QColor(255, 255, 255))) for handle in self.sizing_handles: qp.drawRect(handle) qp.setBrush(QtGui.QBrush()) def focus_selected(self): i = 0 pos_sum = QPoint(0 ,0) for sequence in self.animation_data.selected: for frame in sequence.selected: pos_sum = frame.center() i += 1 self.center_camera(pos_sum / i) def center_sequence(self): if self.animation_data.active_frame is not None: self.center_camera(self.animation_data.active_frame.center()) def center_camera(self, point: QPoint) -> None: """ Centers the camera on a point on the spritesheet""" self.camera = QPoint(point.x() - self.width()/(2*self.scale), point.y() - self.height()/(2*self.scale)) self.constrain_camera() def constrain_camera(self): if self.spritesheet_image is None: return if self.camera.x() < 0: self.camera.setX(0) if self.camera.x() > self.spritesheet_image.width() - (self.frameRect().width() / self.scale): self.camera.setX(self.spritesheet_image.width() - (self.frameRect().width() / self.scale)) if self.camera.y() < 0: self.camera.setY(0) if self.camera.y() > self.spritesheet_image.height() - (self.frameRect().height() / self.scale): self.camera.setY(self.spritesheet_image.height() - (self.frameRect().height() / self.scale)) def focus_alter_frame(self, frame=None): if frame is None: frame = self.animation_data.active_frame if frame is None: return self.center_camera(frame.center()) self.mode = ViewerMode.ALTER_SELECTION self.calc_sizing_handles() self.update() def wheelEvent(self, event): """ Zoom in or out """ # If a spritesheet has not been loaded, do nothing if self.spritesheet_image is None: return # Zoom in / Out of the spritesheet if event.angleDelta().y() > 0: self.zoom_in() else: self.zoom_out() def mousePressEvent(self, mouse): """ Controls for spritesheet manipulation """ if self.isPanning is True or self.spritesheet_image is None: return # Zooming in / out with mouse wheel if mouse.button() == Qt.MidButton or mouse.button() == Qt.RightButton: self.mouse_press_pos = mouse.pos() self.setCursor(Qt.SizeAllCursor) self.camera_old = self.camera self.isPanning = True # Selection of spritesheet pixels if mouse.button() == Qt.LeftButton: self.left_mouse_down = True self.mouse_press_pos = mouse.pos() if self.mode == ViewerMode.ALTER_SELECTION and self.animation_data.active_sequence is not None: mouse_rel = self.view2sheet(mouse.pos()) # If sizing handle or move frame selected, # set sizing mode and save current frame for its position if self.animation_data.active_frame is not None: for i in range(0, len(self.sizing_handles)): if self.sizing_handles[i].contains(mouse.pos()): self.sizing_mode = SizingMode(i) self.original_frame_positions = [self.animation_data.active_frame.translated(0, 0)] return if self.animation_data.active_frame.contains(mouse_rel): self.sizing_mode = SizingMode.MOVE_FRAME self.original_frame_positions = [] for frame in self.animation_data.selected_frames(): self.original_frame_positions.append(frame.translated(0, 0)) return # If another frame was selected, set as active frame. key_mods = QtGui.QGuiApplication.queryKeyboardModifiers() frame = self.animation_data.active_sequence.frame_at_pos(mouse_rel) if self.animation_data.active_sequence is None: print("No active sequence") if frame is None: self.animation_data.active_sequence.selected = [] self.animation_data.active_frame = None else: if key_mods == Qt.ControlModifier: # Select an additional frame self.animation_data.active_sequence.select(frame) elif key_mods == Qt.ShiftModifier: # Select a range of frames index_a = self.animation_data.active_sequence.active_frame_index() index_b = self.animation_data.active_sequence.frame_index(frame) if index_a > index_b: index_a, index_b = index_b, index_a for i in range(index_a, index_b + 1): self.animation_data.active_sequence.select(self.animation_data.active_sequence.frames[i]) else: # Clear selection and add new frame self.animation_data.active_sequence.set_sole(frame) self.animation_data.active_frame = frame #if key_mods self.animation_data_changed_signal.emit() # Click once to select, click once again to move frame self.left_mouse_down = False self.update() if self.mode == ViewerMode.NEW_FRAME: # If no active sequence, createa a new one if self.animation_data.active_sequence is None: self.animation_data.new_sequence(active=True) logging.info("New sequence created") # Create a new frame cord = self.view2sheet(mouse.pos()) self.animation_data.active_sequence.add_frame(AnimationFrame(cord)) self.animation_data_changed_signal.emit() logging.info("New frame created at X:%s Y:%s" % (cord.x(), cord.y())) # Zooming in / out with zoom tool if self.mode == ViewerMode.ZOOM: if mouse.button() == Qt.LeftButton: self.setCursor(self.zoom_in_cursor) elif mouse.button() == Qt.RightButton: self.setCursor(self.zoom_out_cursor) def mouseReleaseEvent(self, mouse): if self.animation_data is None: return if mouse.button() == Qt.MidButton or mouse.button() == Qt.RightButton: self.isPanning = False self.reset_cursor() # Zooming in / out with zoom tool if self.mode == ViewerMode.ZOOM: if mouse.button() == Qt.LeftButton: self.zoom_in() self.reset_cursor() elif mouse.button() == Qt.RightButton: self.zoom_out() self.reset_cursor() if mouse.button() == Qt.LeftButton: self.left_mouse_down = False if (self.mode == ViewerMode.ALTER_SELECTION or self.mode == ViewerMode.NEW_FRAME) and self.animation_data.active_frame is not None: self.sizing_mode = None self.animation_data.active_frame.normalize() frame_start = self.view2sheet(self.mouse_press_pos) frame_end = self.view2sheet(mouse) self.update() #Delete active frame if size is zero if self.animation_data.active_frame is not None: frame = self.animation_data.active_frame if frame.width() == 0 or frame.height() == 0: del self.animation_data.active_frame self.animation_data_changed_signal.emit() def mouseMoveEvent(self, mouse): self.last_mouse_pos = mouse.pos() if self.isPanning: # Move spritesheet frame according to mouse displacement mouse_pos_change = (mouse.pos() - self.mouse_press_pos) / self.scale self.camera = self.camera_old - mouse_pos_change self.constrain_camera() self.calc_sizing_handles() # Creating a new frame if self.mode == ViewerMode.NEW_FRAME: if self.left_mouse_down: # Adjust size of new frame selection clicked_pos = self.view2sheet(self.mouse_press_pos) mouse_pos = self.view2sheet(mouse.pos()) frame = self.animation_data.active_frame frame.setTopLeft(clicked_pos) frame.setBottomRight(QPoint(mouse_pos.x()-1, mouse_pos.y()-1)) self.animation_data_changed_signal.emit() # Altering an existing frame elif self.mode == ViewerMode.ALTER_SELECTION: if self.animation_data.active_frame is not None and self.animation_data.active_frame in self.animation_data.active_sequence.selected: a_frame = self.animation_data.active_frame mouse_rel = self.view2sheet(mouse.pos()) if self.sizing_mode is None: # self.sizing_handles -> contains 8 rects self.setCursor(Qt.ArrowCursor) if a_frame.contains(mouse_rel): self.setCursor(self.move_frame_cursor) for i in range(0, len(self.sizing_handles)): if self.sizing_handles[i].contains(mouse.pos()): self.setCursor(self.sizing_handle_cursors[i]) elif self.left_mouse_down: # Position = original + (mouse_click_pos - mouse_current_pos) delta_mouse = self.view2sheet(self.mouse_press_pos) - self.view2sheet(mouse.pos()) if self.sizing_mode is SizingMode.MOVE_FRAME: selected_frames = self.animation_data.selected_frames() i = 0 for frame in self.original_frame_positions: selected_frames[i].moveTo(frame.topLeft() - delta_mouse) i += 1 elif self.sizing_mode is SizingMode.TOP_LEFT: a_frame.setTopLeft(self.original_frame.topLeft() - delta_mouse) elif self.sizing_mode is SizingMode.TOP: a_frame.setTop(self.original_frame.top() - delta_mouse.y()) elif self.sizing_mode is SizingMode.TOP_RIGHT: a_frame.setTopRight(self.original_frame.topRight() - delta_mouse) elif self.sizing_mode is SizingMode.RIGHT: a_frame.setRight(self.original_frame.right() - delta_mouse.x()) elif self.sizing_mode is SizingMode.BOTTOM_RIGHT: a_frame.setBottomRight(self.original_frame.bottomRight() - delta_mouse) elif self.sizing_mode is SizingMode.BOTTOM: a_frame.setBottom(self.original_frame.bottom() - delta_mouse.y()) elif self.sizing_mode is SizingMode.BOTTOM_LEFT: a_frame.setBottomLeft(self.original_frame.bottomLeft() - delta_mouse) elif self.sizing_mode is SizingMode.LEFT: a_frame.setLeft(self.original_frame.left() - delta_mouse.x()) self.animation_data_changed_signal.emit() self.calc_sizing_handles() self.update() def keyPressEvent(self, e: QtGui.QKeyEvent) -> None: print("keypress") a_frame = self.animation_data.active_frame self.setFocus() # Theres got to be a better way to do this modifiers = QtWidgets.QApplication.keyboardModifiers() if modifiers & Qt.ControlModifier: if e.key() == Qt.Key_Up: a_frame.shift.setY(a_frame.shift.y() - 1) if e.key() == Qt.Key_Down: a_frame.shift.setY(a_frame.shift.y() + 1) if e.key() == Qt.Key_Left: a_frame.shift.setX(a_frame.shift.x() - 1) if e.key() == Qt.Key_Right: a_frame.shift.setX(a_frame.shift.x() + 1) else: # Move all frames selected for sequence in self.animation_data.selected: for frame in sequence.selected: if e.key() == Qt.Key_Up: frame.translate( 0, -1 ) elif e.key() == Qt.Key_Down: frame.translate(0, 1) elif e.key() == Qt.Key_Left: frame.translate(-1, 0) elif e.key() == Qt.Key_Right: frame.translate(1, 0) elif e.key() == Qt.Key_F: self.focus_selected() self.calc_sizing_handles() self.update() self.animation_data_changed_signal.emit() def enterEvent(self, event): self.update() def leaveEvent(self, event): self.update() def reset_cursor(self): if self.mode == ViewerMode.NEW_FRAME: self.setCursor(Qt.BlankCursor) elif self.mode == ViewerMode.ALTER_SELECTION: self.setCursor(Qt.ArrowCursor) elif self.mode == ViewerMode.ZOOM: self.setCursor(self.zoom_cursor) else: self.setCursor(Qt.ArrowCursor) def view2sheet(self, cord): #Get mouse position relative to the spritesheet return QPoint(math.floor(cord.x() / self.scale) + self.camera.x(), math.floor(cord.y() / self.scale) + self.camera.y()) def sheet2view(self, cord): #Get spritesheet position relative to mouse position return QPoint(math.floor((cord.x() - self.camera.x()) * self.scale), math.floor((cord.y() - self.camera.y()) * self.scale))
def paintEvent(self, event): super().paintEvent(event) painter = QPainter(self) #self.painter.setPen(self.backgroundColor) size = self.size() brush = QBrush() #rect = QtCore.QRect(2, 2, size.width()-4, size.height()-4) rect = QtCore.QRect(0, 0, size.width(), size.height()) #painter.fillRect(rect, brush) smallestDim = size.width() if smallestDim > size.height(): smallestDim = size.height() smallestDim = smallestDim / 2 smallestDim -= 2 ## rect.moveCenter(QPoint(size.width()/2,size.height()/2)) center_x = size.width() / 2 center_y = size.height() / 2 centerpoint = QPoint(center_x, center_y) # Draw the border #circle_path = QPainterPath() radius = smallestDim #circle_path.addEllipse(centerpoint,radius,radius) painter.setPen(QPen(QColor('lightgray'), 0)) brush.setStyle(Qtc.SolidPattern) radial = QRadialGradient(center_x, center_y / 2, radius) #radial = QConicalGradient(centerpoint, 50) # Last number is the angle radial.setColorAt(0, Qtc.white) radial.setColorAt(0.8, Qtc.darkGray) painter.setBrush(QBrush(radial)) painter.drawEllipse(centerpoint, radius, radius) #painter.setBrush(QColor('gray')) # painter.drawPath(circle_path) # Draw the colored center radial = QRadialGradient(center_x, center_y / 2, radius) #radial = QRadialGradient(center_x*2/3,center_y*2/3, radius) #radial = QConicalGradient(centerpoint, 0) # Last number is the angle radial.setColorAt(0, Qtc.white) if (self.curState): radial.setColorAt(.7, self.onColor) brush.setColor(self.onColor) painter.setPen(QPen(self.onColor, 0)) else: radial.setColorAt(.7, self.offColor) brush.setColor(self.offColor) painter.setPen(QPen(self.offColor, 0)) brush.setStyle(Qtc.SolidPattern) #painter.setBrush(brush) painter.setBrush(QBrush(radial)) #radius = radius - 9 if (smallestDim <= 30): radius = radius - 3 elif (smallestDim <= 60): radius = radius - 4 elif (smallestDim <= 100): radius = radius - 5 elif (smallestDim <= 200): radius = radius - 6 elif (smallestDim <= 300): radius = radius - 7 else: radius = radius - 9 painter.drawEllipse(centerpoint, radius, radius)
@pytest.mark.parametrize('color, expected', [ (QColor('red'), 'rgba(255, 0, 0, 255)'), (QColor('blue'), 'rgba(0, 0, 255, 255)'), (QColor(1, 3, 5, 7), 'rgba(1, 3, 5, 7)'), ]) def test_qcolor_to_qsscolor(color, expected): assert qtutils.qcolor_to_qsscolor(color) == expected def test_qcolor_to_qsscolor_invalid(): with pytest.raises(qtutils.QtValueError): qtutils.qcolor_to_qsscolor(QColor()) @pytest.mark.parametrize('obj', [ QPoint(23, 42), QUrl('http://www.qutebrowser.org/'), ]) def test_serialize(obj): """Test a serialize/deserialize round trip. Args: obj: The object to test with. """ new_obj = type(obj)() qtutils.deserialize(qtutils.serialize(obj), new_obj) assert new_obj == obj class TestSerializeStream:
class Snip(QWidget): startPos = QPoint(0, 0) endPos = QPoint(0, 0) def __init__(self, args, mainwindow_class_self): super().__init__() self.args = args self.gcp_eng = mainwindow_class_self.ocr_eng self.is_cut_newline = mainwindow_class_self.is_cut_newline screen = QApplication.primaryScreen() # TODO 複数スクリーンに対応 # 関数screenShotのsnipScreen.copyあたりでID指定できればいけそう # screens = [screen for screen in QGuiApplication.screens()] self.snipScreen = screen.grabWindow(QApplication.desktop().winId()) mainwindow_class_self.show() # mainwindowを再描画 def paintEvent(self, event): painter = QPainter(self) painter.setPen(Qt.NoPen) # 描画しない rectSize = QApplication.desktop().screenGeometry() # 切り抜く場所の大きさを決める painter.drawPixmap(rectSize, self.snipScreen) # snipScreenを描写 painterPath = QPainterPath() painterPath.addRect(QRectF(rectSize)) painterPath.addRoundedRect(QRectF(self.startPos, self.endPos), 0, 0) # 範囲指定箇所を指定 painter.setBrush(QBrush(QColor(0, 0, 0, 180))) painter.drawPath(painterPath) def mousePressEvent(self, event): self.startPos = event.pos() def mouseMoveEvent(self, event): self.endPos = event.pos() self.repaint() def mouseReleaseEvent(self, event): self.endPos = event.pos() self.capture() def capture(self): # 右下から左上に選択したときの処理 if self.startPos.x() > self.endPos.x(): self.startPos, self.endPos = self.endPos, self.startPos # QPixmap で選択座標をコピー pmap = self.snipScreen.copy(QRect(self.startPos, self.endPos)) # QPixmap -> Qimage -> binary qimg = pmap.toImage() image_format = 'PNG' bits = QByteArray() buffer = QBuffer(bits) qimg.save(buffer, image_format) # OCR ocr(buffer.data(), self.args.debugmode, self.gcp_eng, self.is_cut_newline) self.close() def keyPressEvent(self, event): """ ESCボタンでキャプチャ終了 """ if event.key() == Qt.Key_Escape: self.close()
def setScrollPosition(self, x, y): ''' Sets the view reticle to an absolute scroll position ''' point = QPoint(x, y) self.page().mainFrame().setScrollPosition(point)
def createCurveIcons(self): pix = QPixmap(self.m_iconSize) painter = QPainter() gradient = QLinearGradient(0, 0, 0, self.m_iconSize.height()) gradient.setColorAt(0.0, QColor(240, 240, 240)) gradient.setColorAt(1.0, QColor(224, 224, 224)) brush = QBrush(gradient) # The original C++ code uses undocumented calls to get the names of the # different curve types. We do the Python equivalant (but without # cheating). curve_types = [ (n, c) for n, c in QEasingCurve.__dict__.items() if isinstance(c, QEasingCurve.Type) and c != QEasingCurve.Custom ] curve_types.sort(key=lambda ct: ct[1]) painter.begin(pix) for curve_name, curve_type in curve_types: painter.fillRect(QRect(QPoint(0, 0), self.m_iconSize), brush) curve = QEasingCurve(curve_type) if curve_type == QEasingCurve.BezierSpline: curve.addCubicBezierSegment(QPointF(0.4, 0.1), QPointF(0.6, 0.9), QPointF(1.0, 1.0)) elif curve_type == QEasingCurve.TCBSpline: curve.addTCBSegment(QPointF(0.0, 0.0), 0, 0, 0) curve.addTCBSegment(QPointF(0.3, 0.4), 0.2, 1, -0.2) curve.addTCBSegment(QPointF(0.7, 0.6), -0.2, 1, 0.2) curve.addTCBSegment(QPointF(1.0, 1.0), 0, 0, 0) painter.setPen(QColor(0, 0, 255, 64)) xAxis = self.m_iconSize.height() / 1.5 yAxis = self.m_iconSize.width() / 3.0 painter.drawLine(0, xAxis, self.m_iconSize.width(), xAxis) painter.drawLine(yAxis, 0, yAxis, self.m_iconSize.height()) curveScale = self.m_iconSize.height() / 2.0 painter.setPen(Qt.NoPen) # Start point. painter.setBrush(Qt.red) start = QPoint(yAxis, xAxis - curveScale * curve.valueForProgress(0)) painter.drawRect(start.x() - 1, start.y() - 1, 3, 3) # End point. painter.setBrush(Qt.blue) end = QPoint(yAxis + curveScale, xAxis - curveScale * curve.valueForProgress(1)) painter.drawRect(end.x() - 1, end.y() - 1, 3, 3) curvePath = QPainterPath() curvePath.moveTo(QPointF(start)) t = 0.0 while t <= 1.0: to = QPointF(yAxis + curveScale * t, xAxis - curveScale * curve.valueForProgress(t)) curvePath.lineTo(to) t += 1.0 / curveScale painter.setRenderHint(QPainter.Antialiasing, True) painter.strokePath(curvePath, QColor(32, 32, 32)) painter.setRenderHint(QPainter.Antialiasing, False) item = QListWidgetItem() item.setIcon(QIcon(pix)) item.setText(curve_name) self.m_ui.easingCurvePicker.addItem(item) painter.end()
numpy.savetxt(file_path, map_matrix, fmt='%d') def load_map(self, file_path): """ read the map from a numpy matrix """ # 加转置保证地图文件和ui画面上物品位置匹配 map_matrix = numpy.loadtxt(file_path, dtype=int) self.path.clear() self.wall.clear() self.set_map_size(map_matrix.shape[1], map_matrix.shape[0]) # 存在才画出来 if len(numpy.argwhere(map_matrix == RABBIT)): self.set_rabbit(QPoint(numpy.argwhere(map_matrix == RABBIT)[0][1], numpy.argwhere(map_matrix == RABBIT)[0][0])) if len(numpy.argwhere(map_matrix == RADISH)): self.set_radish(QPoint(numpy.argwhere(map_matrix == RADISH)[0][1], numpy.argwhere(map_matrix == RADISH)[0][0])) temp_wall = numpy.argwhere(map_matrix == WALL) for i in range(temp_wall.shape[0]): self.set_wall(QPoint(temp_wall[i][1], temp_wall[i][0])) if __name__ == "__main__": myMap = Map(5, 5) print(myMap.on_special_object("wall", QPoint(-1, 1))) print(myMap.is_valid(QPoint(-1, 1))) myMap.load_map("initMap.txt") print(myMap.a_star_searching()) print(myMap.path)
class ImageArea(QWidget): def __init__(self, width, height): super(ImageArea, self).__init__() self.imgPixmap = None self.scaledImg = None self.img_offset = QPoint(0, 0) # initialize offset self.isLeftPressed = bool(False) self.isImgLabelArea = bool(True) # mouse into the area of image self.layout_width = width # the width of the windows can display image self.layout_height = height # the height of the windows can display image self.select_mode = False # select image by user self.select_rect = QRect(0, 0, 0, 0) # the info of select area self.select_begin_point = QPoint(0, 0) # for show the info of the image self.lblTest = QtWidgets.QLabel(self) self.lblTest.setGeometry(10, 550, 300, 20) self.lblTest.setText("Offset: (0, 0)") def update_image(self, pixmap): self.imgPixmap = pixmap self.scaledImg = self.imgPixmap.copy() self.img_offset = QPoint(0, 0) self.update() # repaint the image def paintEvent(self, event): self.imgPainter = QPainter() # display image self.imgPainter.begin(self) self.lblTest.setText("Offset: ({0}, {1})".format( self.img_offset.x(), self.img_offset.y())) if self.scaledImg is not None: self.imgPainter.drawPixmap( self.img_offset, self.scaledImg) # display image with offset if self.select_mode: # display select frame self.rectPainter = QPainter() self.rectPainter.begin(self) self.rectPainter.setPen(QPen(Qt.red, 2, Qt.DashLine)) self.rectPainter.drawRect(self.select_rect) self.rectPainter.end() self.imgPainter.end() def mousePressEvent(self, event): if event.buttons() == QtCore.Qt.LeftButton: print("Click left mouse") self.isLeftPressed = True self.preMousePosition = event.pos( ) # get mouse position when click mouse if self.select_mode: self.select_begin_point = event.pos() def wheelEvent(self, event): angle = event.angleDelta() / 8 # QPoint() wheel scroll distance angle_x = angle.x() # horizontal scroll distance angle_y = angle.y() # vertical scroll distance if angle_y > 0: # scroll up print("Scroll up") self.scaledImg = self.imgPixmap.scaled( self.scaledImg.width() + self.imgPixmap.width() // 20, self.scaledImg.height() + self.imgPixmap.height() // 20, Qt.KeepAspectRatio, transformMode=Qt.SmoothTransformation ) # change the size of image # try to keep the mouse point to the same position after the size changed new_width = event.x() - (self.scaledImg.width() * (event.x() - self.img_offset.x())) \ / (self.scaledImg.width() - self.imgPixmap.width() // 20) new_height = event.y() - (self.scaledImg.height() * (event.y() - self.img_offset.y())) \ / (self.scaledImg.height() - self.imgPixmap.height() // 20) self.img_offset = QPoint(new_width, new_height) # update offset self.update() else: # scroll down print("Scroll down") self.scaledImg = self.imgPixmap.scaled( self.scaledImg.width() - self.imgPixmap.width() // 20, self.scaledImg.height() - self.imgPixmap.height() // 20, Qt.KeepAspectRatio, transformMode=Qt.SmoothTransformation ) # change the size of image # try to keep the mouse point to the same position after the size changed new_width = event.x() - (self.scaledImg.width() * (event.x() - self.img_offset.x())) \ / (self.scaledImg.width() + self.imgPixmap.width() // 20) new_height = event.y() - (self.scaledImg.height() * (event.y() - self.img_offset.y())) \ / (self.scaledImg.height() + self.imgPixmap.height() // 20) self.img_offset = QPoint(new_width, new_height) # update offset self.update() def mouseReleaseEvent(self, event): if event.buttons() == QtCore.Qt.LeftButton: self.isLeftPressed = False print("Release left mouse") elif event.button() == Qt.RightButton: self.img_offset = QPoint(0, 0) # reset the offset self.scaledImg = self.imgPixmap.scaled( self.imgPixmap.width(), self.imgPixmap.height(), Qt.KeepAspectRatio, transformMode=Qt.SmoothTransformation) # 置为初值 self.update() print("Release right mouse") def mouseMoveEvent(self, event): if self.isLeftPressed: if self.select_mode: self.select_offset = event.pos( ) - self.select_begin_point # total offset of mouse when selecting self.select_rect = QRect(self.select_begin_point.x(), self.select_begin_point.y(), abs(self.select_offset.x()), abs(self.select_offset.y())) else: print("Click left mouse & move") width_gap = self.layout_width - self.scaledImg.width( ) # the gap between display window & image print(width_gap, self.layout_width, self.scaledImg.width()) height_gap = self.layout_height - self.scaledImg.height( ) # the gap between display window & image print(height_gap, self.layout_height, self.scaledImg.height()) once_offset = event.pos( ) - self.preMousePosition # the offset of this movement self.img_offset = self.img_offset + once_offset # update offset # if width of image smaller than width of layout if width_gap > 0: if self.img_offset.x() < 0: self.img_offset.setX(0) elif self.img_offset.x() > width_gap: self.img_offset.setX(width_gap) # if width of image bigger than width of layout else: if self.img_offset.x() > 0: self.img_offset.setX(0) elif self.img_offset.x() < width_gap: self.img_offset.setX(width_gap) # if height of image smaller than height of layout if height_gap > 0: if self.img_offset.y() < 0: self.img_offset.setY(0) elif self.img_offset.y() > height_gap: self.img_offset.setY(height_gap) # if height of image bigger than height of layout else: if self.img_offset.y() > 0: self.img_offset.setY(0) elif self.img_offset.y() < height_gap: self.img_offset.setY(height_gap) self.preMousePosition = event.pos( ) # update mouse position on the window self.update() def select_mode_change(self, is_select_mode): self.select_mode = is_select_mode
class Map: """ Map(width, height) """ def __init__(self, width=8, height=8): self.width = width self.height = height self.wall = [] # QPoint Type self.path = [] # QPoint Type self.rabbit = QPoint(0, 0) self.radish = QPoint(width - 1, height - 1) def set_map_size(self, width, height): self.width = width self.height = height def set_wall(self, position): """ The type of parameter:"position" is QPoint """ self.wall.append(position) def set_radish(self, position): self.radish = position def set_rabbit(self, position): self.rabbit = position def clear_one_wall(self, position): if not self.on_special_object("radish", position): if not self.on_special_object("rabbit", position): if self.on_special_object("wall", position): wall_index = self.wall.index(position) self.wall.pop(wall_index) def clear_all_wall(self): self.wall.clear() def on_special_object(self, spe_object, position): """ To judge whether the selected position is on the special object :param spe_object: "wall", "radish", "rabbit" :param position: QPoint type :return: True or False """ if spe_object == "wall": for i in range(len(self.wall)): if self.wall[i] == position: return True return False elif spe_object == "radish": if self.radish == position: return True else: return False elif spe_object == "rabbit": if self.radish == position: return True else: return False def out_map(self, position): if position.x() < 0 or position.x() > self.width - 1 or \ position.y() < 0 or position.y() > self.height - 1: return True else: return False def is_valid(self, position): """ when the point is not in the wall or out of the map, it is valid. :param position: QPoint Type position :return: True or False """ if self.out_map(position) or \ self.on_special_object("wall", position): return False else: return True def manhattan_length(self, pos1, pos2): """ compute the manhattan distance between pos1 and pos2 """ distance = pos1-pos2 return distance.manhattanLength() def a_star_searching(self): """ Use A* algorithm to find the best path between rabbit and radish :return: """ # time.clock() to compute the running time of a_star_searching if self.rabbit == QPoint(-1,-1) or self.radish == QPoint(-1,-1): return [False] start_time = time.clock() self.path.clear() open_list, close_list = [], [] # temp_point 在生成open表时有用,current_point表示目前搜索到的点 temp_point, current_point = QPoint(), QPoint() path_length = [[0 for i in range(self.height)] for j in range(self.width)] parent_point = [[QPoint(-1, -1) for i in range(self.height)] for j in range(self.width)] min_cost, temp_cost, sequence= 0, 0, 0 close_list.append(self.rabbit) while True: open_list.clear() # find the adjacent points of every point in close_list for i in range(len(close_list)): current_point = close_list[i] # temp_point is the adjacent points(4) of current_point temp_point = [copy.deepcopy(current_point) for i in range(4)] temp_point[0].setX(temp_point[0].x()-1) temp_point[1].setX(temp_point[1].x()+1) temp_point[2].setY(temp_point[2].y()-1) temp_point[3].setY(temp_point[3].y()+1) for j in range(4): if close_list.count(temp_point[j]) == 0 : if open_list.count(temp_point[j]) == 0: if self.is_valid(temp_point[j]): # use deepcopy to assure the open_list unchangeable when # the temp_point changes open_list.append(copy.deepcopy(temp_point[j])) if len(open_list) == 0: return [False] # find all the distance of between points in open_list and beginning point for i in range(len(open_list)): current_point = open_list[i] # makes the min_cost as large as possible min_cost = self.width * self.height for j in range(len(close_list)): temp_point = close_list[j] if self.manhattan_length(current_point, temp_point) == 1: temp_cost = path_length[temp_point.x()][temp_point.y()] + 1 if temp_cost < min_cost: min_cost = copy.deepcopy(temp_cost) sequence = j parent_point[current_point.x()][current_point.y()] = copy.deepcopy(close_list[sequence]) path_length[current_point.x()][current_point.y()] = min_cost min_cost = self.width * self.height for i in range(len(open_list)): current_point = open_list[i] temp_cost = path_length[current_point.x()][current_point.y()] + \ self.manhattan_length(current_point, self.radish) if temp_cost < min_cost: min_cost = temp_cost sequence = i temp_point = copy.deepcopy(open_list[sequence]) close_list.append(temp_point) if temp_point == self.radish: while True: self.path.append(copy.deepcopy(temp_point)) temp_point = parent_point[temp_point.x()][temp_point.y()] if temp_point.x() == -1: return [True, time.clock() - start_time] def save_map(self, file_path): """ save the map as a numpy matrix """ map_matrix = [[BASE_ROAD for i in range(self.width)] for j in range(self.height)] map_matrix = numpy.array(map_matrix).T for i in range(len(self.wall)): map_matrix[self.wall[i].x()][self.wall[i].y()] = WALL map_matrix[self.rabbit.x()][self.rabbit.y()] = RABBIT map_matrix[self.radish.x()][self.radish.y()] = RADISH map_matrix = numpy.array(map_matrix).T numpy.savetxt(file_path, map_matrix, fmt='%d') def load_map(self, file_path): """ read the map from a numpy matrix """ # 加转置保证地图文件和ui画面上物品位置匹配 map_matrix = numpy.loadtxt(file_path, dtype=int) self.path.clear() self.wall.clear() self.set_map_size(map_matrix.shape[1], map_matrix.shape[0]) # 存在才画出来 if len(numpy.argwhere(map_matrix == RABBIT)): self.set_rabbit(QPoint(numpy.argwhere(map_matrix == RABBIT)[0][1], numpy.argwhere(map_matrix == RABBIT)[0][0])) if len(numpy.argwhere(map_matrix == RADISH)): self.set_radish(QPoint(numpy.argwhere(map_matrix == RADISH)[0][1], numpy.argwhere(map_matrix == RADISH)[0][0])) temp_wall = numpy.argwhere(map_matrix == WALL) for i in range(temp_wall.shape[0]): self.set_wall(QPoint(temp_wall[i][1], temp_wall[i][0]))
def run(self, qp): qp.setBrush(QColor(255, 255, 0)) radiys = int(randint(10, 200)) qp.drawEllipse(QPoint(200, 200), radiys, radiys)
def paintEvent(self, e): super(LabeledSlider, self).paintEvent(e) style = self.slider.style() painter = QPainter(self) st_slider = QStyleOptionSlider() st_slider.initFrom(self.slider) st_slider.orientation = self.slider.orientation() length = style.pixelMetric(QStyle.PM_SliderLength, st_slider, self.slider) available = style.pixelMetric(QStyle.PM_SliderSpaceAvailable, st_slider, self.slider) for v, v_str in self.levels: # get the size of the label rect = painter.drawText(QRect(), Qt.TextDontPrint, str(v_str)) if self.slider.orientation() == Qt.Horizontal: # I assume the offset is half the length of slider, therefore # + length//2 x_loc = QStyle.sliderPositionFromValue( self.slider.minimum(), self.slider.maximum(), v, available) + length // 2 # left bound of the text = center - half of text width + L_margin left = x_loc - rect.width() // 2 + self.left_margin bottom = self.rect().bottom() # enlarge margins if clipping if v == self.slider.minimum(): if left <= 0: self.left_margin = rect.width() // 2 - x_loc if self.bottom_margin <= rect.height(): self.bottom_margin = rect.height() self.layout.setContentsMargins(self.left_margin, self.top_margin, self.right_margin, self.bottom_margin) if v == self.slider.maximum( ) and rect.width() // 2 >= self.right_margin: self.right_margin = rect.width() // 2 self.layout.setContentsMargins(self.left_margin, self.top_margin, self.right_margin, self.bottom_margin) else: y_loc = QStyle.sliderPositionFromValue(self.slider.minimum(), self.slider.maximum(), v, available, upsideDown=True) bottom = y_loc + length // 2 + rect.height( ) // 2 + self.top_margin - 3 # there is a 3 px offset that I can't attribute to any metric left = self.left_margin - rect.width() if left <= 0: self.left_margin = rect.width() + 2 self.layout.setContentsMargins(self.left_margin, self.top_margin, self.right_margin, self.bottom_margin) pos = QPoint(left, bottom) painter.drawText(pos, str(v_str)) return
def __init__(self, tab, parent=None): super().__init__(tab, parent) self._args = objreg.get('args') self._pos_perc = (0, 0) self._pos_px = QPoint() self._at_bottom = False
def __init__(self, parent, persepolis_setting): super().__init__(persepolis_setting) self.persepolis_setting = persepolis_setting self.parent = parent self.grandparent = parent.persepolis_main self.persepolis_setting.beginGroup('settings') # initialization self.tries_spinBox.setValue( int(self.persepolis_setting.value('max-tries'))) self.wait_spinBox.setValue( int(self.persepolis_setting.value('retry-wait'))) self.time_out_spinBox.setValue( int(self.persepolis_setting.value('timeout'))) self.connections_spinBox.setValue( int(self.persepolis_setting.value('connections'))) self.rpc_port_spinbox.setValue( int(self.persepolis_setting.value('rpc-port'))) # add support for other languages locale = str(self.persepolis_setting.value('settings/locale')) QLocale.setDefault(QLocale(locale)) self.translator = QTranslator() if self.translator.load(':/translations/locales/ui_' + locale, 'ts'): QCoreApplication.installTranslator(self.translator) # wait_queue wait_queue_list = self.persepolis_setting.value('wait-queue') q_time = QTime(int(wait_queue_list[0]), int(wait_queue_list[1])) self.wait_queue_time.setTime(q_time) # change aria2 path self.aria2_path_pushButton.clicked.connect(self.changeAria2Path) self.aria2_path_checkBox.toggled.connect(self.ariaCheckBoxToggled) aria2_path = self.persepolis_setting.value('settings/aria2_path') self.aria2_path_lineEdit.setEnabled(False) if aria2_path != None: self.aria2_path_checkBox.setChecked(True) self.aria2_path_lineEdit.setText(str(aria2_path)) self.ariaCheckBoxToggled('aria2') if os_type == 'Linux' or os_type == 'FreeBSD' or os_type == 'OpenBSD': for widget in self.aria2_path_checkBox, self.aria2_path_lineEdit, self.aria2_path_pushButton: widget.hide() # save_as_tab self.download_folder_lineEdit.setText( str(self.persepolis_setting.value('download_path'))) self.temp_download_lineEdit.setText( str(self.persepolis_setting.value('download_path_temp'))) # subfolder if str(self.persepolis_setting.value('subfolder')) == 'yes': self.subfolder_checkBox.setChecked(True) else: self.subfolder_checkBox.setChecked(False) # notifications_tab self.volume_label.setText( 'Volume : ' + str(self.persepolis_setting.value('sound-volume'))) self.volume_dial.setValue( int(self.persepolis_setting.value('sound-volume'))) # set style # find available styles(It's depends on operating system and desktop environments). available_styles = QStyleFactory.keys() for style in available_styles: # 'GTK' or 'gtk' styles may cause to crashing! Eliminate them! if 'gtk' not in str(style) and 'GTK' not in str(style): self.style_comboBox.addItem(style) # System >> for system default style # when user select System for style section, the default system style is using. self.style_comboBox.addItem('System') current_style_index = self.style_comboBox.findText( str(self.persepolis_setting.value('style'))) if current_style_index != -1: self.style_comboBox.setCurrentIndex(current_style_index) # available language available_language = [ 'en_US', 'fa_IR', 'ar', 'zh_CN', 'fr_FR', 'pl_PL', 'nl_NL', 'pt_BR', 'es_ES', 'hu', 'tr', 'tr_TR' ] for lang in available_language: self.lang_comboBox.addItem(str(QLocale(lang).nativeLanguageName()), lang) current_locale = self.lang_comboBox.findData( str(self.persepolis_setting.value('locale'))) self.lang_comboBox.setCurrentIndex(current_locale) self.current_icon = self.persepolis_setting.value('icons') # icon size size = ['128', '64', '48', '32', '24', '16'] self.icons_size_comboBox.addItems(size) current_icons_size_index = self.icons_size_comboBox.findText( str(self.persepolis_setting.value('toolbar_icon_size'))) self.icons_size_comboBox.setCurrentIndex(current_icons_size_index) # call setDarkLightIcon if index is changed self.icons_size_comboBox.currentIndexChanged.connect( self.setDarkLightIcon) # set notification notifications = ['Native notification', 'QT notification'] self.notification_comboBox.addItems(notifications) current_notification_index = self.notification_comboBox.findText( str(self.persepolis_setting.value('notification'))) self.notification_comboBox.setCurrentIndex(current_notification_index) # set font font_setting = QFont() font_setting.setFamily(str(self.persepolis_setting.value('font'))) self.fontComboBox.setCurrentFont(font_setting) self.font_size_spinBox.setValue( int(self.persepolis_setting.value('font-size'))) # sound frame self.sound_frame.setEnabled(False) self.enable_notifications_checkBox.toggled.connect(self.soundFrame) if str(self.persepolis_setting.value('sound')) == 'yes': self.enable_notifications_checkBox.setChecked(True) else: self.enable_notifications_checkBox.setChecked(False) # connect folder buttons self.download_folder_lineEdit.setEnabled(False) self.download_folder_pushButton.clicked.connect( self.downloadFolderPushButtonClicked) self.temp_download_lineEdit.setEnabled(False) self.temp_download_pushButton.clicked.connect( self.tempDownloadPushButtonClicked) # dial self.volume_dial.setNotchesVisible(True) self.volume_dial.valueChanged.connect(self.dialChanged) # start_persepolis_if_browser_executed_checkBox if str(self.persepolis_setting.value('browser-persepolis')) == 'yes': self.start_persepolis_if_browser_executed_checkBox.setChecked(True) else: self.start_persepolis_if_browser_executed_checkBox.setChecked( False) # hide window if str(self.persepolis_setting.value('hide-window')) == 'yes': self.hide_window_checkBox.setChecked(True) else: self.hide_window_checkBox.setChecked(False) # tray icon if str(self.persepolis_setting.value('tray-icon')) == 'yes': self.enable_system_tray_checkBox.setChecked(True) else: self.enable_notifications_checkBox.setChecked(False) # show_menubar if str(self.persepolis_setting.value('show-menubar')) == 'yes': self.show_menubar_checkbox.setChecked(True) else: self.show_menubar_checkbox.setChecked(False) if platform.system() == 'Darwin': self.show_menubar_checkbox.setChecked(True) self.show_menubar_checkbox.hide() # show_sidepanel if str(self.persepolis_setting.value('show-sidepanel')) == 'yes': self.show_sidepanel_checkbox.setChecked(True) else: self.show_sidepanel_checkbox.setChecked(False) # show ProgressWindow if str(self.persepolis_setting.value('show-progress')) == 'yes': self.show_progress_window_checkbox.setChecked(True) else: self.show_progress_window_checkbox.setChecked(False) # after download dialog if str(self.persepolis_setting.value('after-dialog')) == 'yes': self.after_download_checkBox.setChecked(True) else: self.after_download_checkBox.setChecked(False) # run persepolis at startup checkBox if str(self.persepolis_setting.value('startup')) == 'yes': self.startup_checkbox.setChecked(True) else: self.startup_checkbox.setChecked(False) # font_checkBox if str(self.persepolis_setting.value('custom-font')) == 'yes': self.font_checkBox.setChecked(True) else: self.font_checkBox.setChecked(False) self.fontCheckBoxState(self.font_checkBox) # keep_awake_checkBox if str(self.persepolis_setting.value('awake')) == 'yes': self.keep_awake_checkBox.setChecked(True) else: self.keep_awake_checkBox.setChecked(False) # columns_tab if str(self.persepolis_setting.value('column0')) == 'yes': self.column0_checkBox.setChecked(True) else: self.column0_checkBox.setChecked(False) if str(self.persepolis_setting.value('column1')) == 'yes': self.column1_checkBox.setChecked(True) else: self.column1_checkBox.setChecked(False) if str(self.persepolis_setting.value('column2')) == 'yes': self.column2_checkBox.setChecked(True) else: self.column2_checkBox.setChecked(False) if str(self.persepolis_setting.value('column3')) == 'yes': self.column3_checkBox.setChecked(True) else: self.column3_checkBox.setChecked(False) if str(self.persepolis_setting.value('column4')) == 'yes': self.column4_checkBox.setChecked(True) else: self.column4_checkBox.setChecked(False) if str(self.persepolis_setting.value('column5')) == 'yes': self.column5_checkBox.setChecked(True) else: self.column5_checkBox.setChecked(False) if str(self.persepolis_setting.value('column6')) == 'yes': self.column6_checkBox.setChecked(True) else: self.column6_checkBox.setChecked(False) if str(self.persepolis_setting.value('column7')) == 'yes': self.column7_checkBox.setChecked(True) else: self.column7_checkBox.setChecked(False) if str(self.persepolis_setting.value('column10')) == 'yes': self.column10_checkBox.setChecked(True) else: self.column10_checkBox.setChecked(False) if str(self.persepolis_setting.value('column11')) == 'yes': self.column11_checkBox.setChecked(True) else: self.column11_checkBox.setChecked(False) if str(self.persepolis_setting.value('column12')) == 'yes': self.column12_checkBox.setChecked(True) else: self.column12_checkBox.setChecked(False) # video_finder try: # Integer casting may raise exception. self.max_links_spinBox.setValue( int(persepolis_setting.value('video_finder/max_links', 3))) except: pass # shortcuts self.qshortcuts_list = [ self.parent.exitAction_shortcut, self.parent.minimizeAction_shortcut, self.parent.removeSelectedAction_shortcut, self.parent.deleteSelectedAction_shortcut, self.parent.moveUpSelectedAction_shortcut, self.parent.moveDownSelectedAction_shortcut, self.parent.addlinkAction_shortcut, self.parent.videoFinderAddLinkAction_shortcut, self.parent.addtextfileAction_shortcut ] self.shortcuts_list = [ self.parent.exitAction_shortcut.key().toString(), self.parent.minimizeAction_shortcut.key().toString(), self.parent.removeSelectedAction_shortcut.key().toString(), self.parent.deleteSelectedAction_shortcut.key().toString(), self.parent.moveUpSelectedAction_shortcut.key().toString(), self.parent.moveDownSelectedAction_shortcut.key().toString(), self.parent.addlinkAction_shortcut.key().toString(), self.parent.videoFinderAddLinkAction_shortcut.key().toString(), self.parent.addtextfileAction_shortcut.key().toString() ] # add shortcuts to the shortcut_table j = 0 for shortcut in self.shortcuts_list: item = QTableWidgetItem(shortcut) # align center item.setTextAlignment(0x0004 | 0x0080) # insert item in shortcut_table self.shortcut_table.setItem(j, 1, item) j = j + 1 # If user doubleclicks on a row, then run showCaptureKeyboardWindow method self.shortcut_table.itemDoubleClicked.connect( self.showCaptureKeyboardWindow) # ok cancel default button self.cancel_pushButton.clicked.connect(self.close) self.defaults_pushButton.clicked.connect( self.defaultsPushButtonPressed) self.ok_pushButton.clicked.connect(self.okPushButtonPressed) # font_checkBox connect self.font_checkBox.stateChanged.connect(self.fontCheckBoxState) # saving initial value of self.persepolis_setting in self.first_key_value_dict # at the end! in the okPushButtonPressed method, first_key_value_dict will compared with second_key_value_dict. # if any thing changed , then a message box notify user about "some changes take effect after restarting persepolis". self.first_key_value_dict = {} for member in self.persepolis_setting.allKeys(): self.first_key_value_dict[member] = str( self.persepolis_setting.value(member)) # if style_comboBox is changed, self.styleComboBoxChanged is called. self.style_comboBox.currentIndexChanged.connect( self.styleComboBoxChanged) self.styleComboBoxChanged() self.color_comboBox.currentIndexChanged.connect(self.setDarkLightIcon) self.persepolis_setting.endGroup() # setting window size and position size = self.persepolis_setting.value('PreferencesWindow/size', QSize(578, 565)) position = self.persepolis_setting.value('PreferencesWindow/position', QPoint(300, 300)) self.resize(size) self.move(position)
class WindMill(QLabel): set_ = pyqtSignal() def __init__(self, father, top): super().__init__('', father) self.set_.connect(set_wall) self.father, self.top = father, top self.setGeometry(0, 0, 75, 75) self.pix = QPixmap('image/windmill.png') self.setToolTip('来点好玩的') self.handle = False self.pressed = False self.move_pos = QPoint(0, 0) self.add = 0 self.angle = 0 self.downloading = False self.menu = QMenu(self) self.set_action = self.top.tray.set_action self.exit_action = self.top.tray.exit_action self.download_action = QAction(QIcon('image/download.png'), '下载', self) self.download_action.triggered.connect(self.download) self.menu.addActions( [self.set_action, self.download_action, self.exit_action]) def paintEvent(self, p): painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) painter.translate(37.5, 38) painter.rotate(self.angle) painter.translate(-37.5, -38) painter.drawPixmap(12, 13, 50, 50, self.pix) def event(self, e): # 鼠标移进移出 if e.type() == QEvent.Enter: self.setCursor(Qt.PointingHandCursor) self.top.right_frame.scale_state = 1 elif e.type() == QEvent.Leave: self.setCursor(Qt.ArrowCursor) if self.top.right_frame.like_label.width() == 40: self.top.right_frame.scale_delay = 50 self.top.right_frame.scale_state = -1 return super().event(e) def contextMenuEvent(self, e): self.menu.exec_(self.mapToGlobal(e.pos())) def mousePressEvent(self, e): self.pressed = True self.move_pos = e.pos() def mouseReleaseEvent(self, e): self.pressed = False if self.handle: self.handle = False else: if e.button() == 1: self.switch() def switch(self, type_=False): if not self.downloading: self.father.abort = False self.add = 1 self.downloading = True self.setToolTip('点击取消') self.top.set.api_choose.setEnabled(False) self.top.set.category_choose.setEnabled(False) Thread(target=self.process_download).start() elif not self.father.abort and not type_: # 停止 self.father.abort = True def mouseMoveEvent(self, e): if self.pressed: self.handle = True self.top.position = [ self.top.position[0] + e.x() - self.move_pos.x(), self.top.position[1] + e.y() - self.move_pos.y() ] self.top.setGeometry(*self.top.position, *self.top.size_) def process_download(self): # 开始下载 try: self.top.next_wall() except: # 无论什么错误都忽略 pass # 下载完毕 self.downloading = False self.setToolTip('来点好玩的') self.add = -1 self.father.step_time = 0 if self.top.config['play_what'] == '网络': self.top.set.api_choose.setEnabled(True) self.top.set.category_choose.setEnabled(True) if not self.father.abort and self.top.config['play_what'] != '本地': self.set_.emit() self.father.abort = False self.father.process_signal.emit(0) self.top.right_frame.reload_pix() if self.top.api.name + '_' + str( self.top.api.current_id) in self.top.data['download_list']: self.download_action.setIcon(QIcon('image/cancel_download.png')) self.download_action.setText('删除') else: self.download_action.setIcon(QIcon('image/download.png')) self.download_action.setText('下载') def download(self): try: if self.top.api.current_id and self.top.config['directory'] != 0: if self.download_action.text() == '下载': copyfile( 'image/wall.jpg', join( self.top.config['directory'], self.top.api.name + '_' + str(self.top.api.current_id) + '.jpg')) self.top.data['download_list'].append( self.top.api.name + '_' + str(self.top.api.current_id)) self.top.dump_data('data') self.download_action.setIcon( QIcon('image/cancel_download.png')) self.download_action.setText('删除') else: remove( join( self.top.config['directory'], self.top.api.name + '_' + str(self.top.api.current_id) + '.jpg')) self.top.data['download_list'].remove( self.top.api.name + '_' + str(self.top.api.current_id)) self.top.dump_data('data') self.download_action.setIcon(QIcon('image/download.png')) self.download_action.setText('下载') except: return
class Example(QWidget): overlay: QImage #Overlay(Накладываем) Picture on Window timer: QTimer #Timet init painter: QPainter Colors: list arr_points: list DeltaX: int DeltaY: int SelfHeight: int LastAngle: int stationSize: list LastMousePosition: QPoint AllData: pd.DataFrame #WithDates: pd.DataFrame toolTipWidget: QLabel pytrends: TrendReq def __init__(self): super().__init__() self.initUI() def keyPressEvent(self, event): if event.key() == 16777216: #Esc #self.FileSaving(self.arr_points, FILE_NAME) sys.exit() #Programm Closing elif event.key() == 16777249: #Ctrl self.UpdateGoogleData() #self.FileSaving(self.GetGoogleData(stationsName), FILE_DATA_NAME) def UpdateGoogleData(self): self.pytrends = TrendReq(hl='ru-RU', tz=360) for i, row in self.AllData.iterrows(): if not row['popularity_mean'] > 0 or IS_FULL_LOAD: station_popularity_mean, station_popularity = self.GetStation_popularity( row['Name'], self.pytrends) print(row['Name'] + ' ' + str(round(station_popularity_mean, 2))) self.AllData.at[i, 'popularity_mean'] = station_popularity_mean self.AllData.at[i, 'popularity'] = ':'.join(station_popularity) else: print(row['Name'] + ' ' + str(round(row['popularity_mean'], 2)) + ' old') # self.FileDrawing(False) QApplication.processEvents() # if i>10: # break #self.WithDates.to_csv(FILE_DATES_NAME, index = False, sep=',', encoding='utf-8-sig') if i % 10 == 0: self.AllData.to_csv(FILE_DATA_NAME, index=False, sep=',', encoding='utf-8-sig') print('All Loaded!') def GetStation_popularity(self, station_name, trends_object): # station_name = 'Тульская' # timeframe='today 5-y' suggestions_dict = self.pytrends.suggestions(keyword=station_name + ' Станция метрополитена') # kw_list = station_name 'type:Moscow Metro'] suggestions = [ x for x in suggestions_dict if x['title'] == station_name ] if len(suggestions) > 0: kw_list = [suggestions[0]['mid']] print(' ' + suggestions[0]['type']) else: return 0 # kw_list = [station_name] trends_object.build_payload(kw_list, cat=0, geo='RU', timeframe='2017-01-01 2018-11-01', gprop='') interest = trends_object.interest_over_time() #print(interest) #self.WithDates.set_index('date') #self.WithDates = self.WithDates.append(interest) print(interest) print(list(interest.columns.values)) mean = interest.mean() if len(list(mean)) > 0: return mean[0], interest['/m/06v6qd'] else: return 0 def mousePressEvent(self, event): mousePoint = event.pos() self.LastMousePosition = mousePoint if event.button() == 1: # self.painter.setFont(QFont('Arial', 111)) # self.painter.drawText(QPoint(200,200), 'HELLO') WindowW = self.frameGeometry().width() # WindowSize WindowH = self.frameGeometry().height() # WindowSize imgH = self.overlay.height() # Original Picture Size imgW = self.overlay.width() # Original Picture Size img = self.overlay.scaledToHeight(self.SelfHeight, Qt.FastTransformation) #AdjX = (WindowW-img.width())/2 ResultX = imgW * (mousePoint.x() - self.DeltaX) / img.width() ResultY = imgH / 100 * ((mousePoint.y() - self.DeltaY) / (self.SelfHeight / 100)) #eraser = 7 #self.painter.drawEllipse(QPoint(ResultX, ResultY), RADIUS, RADIUS) for i, row in self.AllData.iterrows(): if ResultX >= row['X'] - (row['popularity_mean'] + ADDITIONAL) /2 and \ ResultX <= row['X'] + (row['popularity_mean'] + ADDITIONAL) /2 and \ ResultY >= row['Y'] - (row['popularity_mean'] + ADDITIONAL) /2 and \ ResultY <= row['Y'] + (row['popularity_mean'] + ADDITIONAL) /2: text = row['Name'] + ', ' + str( round(row['popularity_mean'], 1)) + '%' self.toolTipWidget.setText(text) self.toolTipWidget.move(event.pos()) self.toolTipWidget.adjustSize() self.toolTipWidget.show() #self.painter.eraseRect(QRect(QPoint(ResultX-RADIUS/2-eraser, ResultY-RADIUS/2-eraser), QPoint(ResultX+radius/2+eraser, ResultY+radius/2+eraser))) self.arr_points.append((ResultX, ResultY)) #print([(round(x[0]), round(x[1])) for x in self.arr_points]) self.update() #Redraw if event.button() == 2: WindowW = self.frameGeometry().width() # WindowSize WindowH = self.frameGeometry().height() # WindowSize imgH = self.overlay.height() # Original Picture Size imgW = self.overlay.width() # Original Picture Size img = self.overlay.scaledToHeight(self.SelfHeight, Qt.FastTransformation) #AdjX = (WindowW-img.width())/2 ResultX = imgW * (mousePoint.x() - self.DeltaX) / img.width() ResultY = imgH / 100 * ((mousePoint.y() - self.DeltaY) / (self.SelfHeight / 100)) #eraser = 7 self.painter.drawEllipse(QPoint(ResultX, ResultY), RADIUS, RADIUS) #self.painter.eraseRect(QRect(QPoint(ResultX-RADIUS/2-eraser, ResultY-RADIUS/2-eraser), QPoint(ResultX+radius/2+eraser, ResultY+radius/2+eraser))) self.arr_points.append((ResultX, ResultY)) #print([(round(x[0]), round(x[1])) for x in self.arr_points]) self.update() #Redraw def mouseReleaseEvent(self, event): self.point = None self.toolTipWidget.hide() ''' def FileSaving(self, arr: list, fileName: str): with open(fileName, 'w') as f: for item in arr: f.write(','.join(str(x) for x in item) + '\n') f.close() def FileReading(self, fileName: str): with open(fileName, 'r') as f: names = f.read().split('\n') f.close() #print(names) return [x.split(',') for x in names] def GetGoogleData(self, namesSt: list): stationSizes = [] for station in namesSt: sz = self.GetStationpopularity_meanarity([station], self.pytrends) if sz>0: stationSizes.append([station, sz]) print(station+': '+str(round(sz, 1))) else: print(station+' error') return stationSizes ''' def FileDrawing(self, animate): if not animate: self.timer.stop() penLine = QPen(QColor(Qt.red)) penLine.setWidth(10) for i, row in self.AllData.iterrows(): penEllipse = QPen(self.Colors[int(row['Line'].replace('A', '')) - 1]) penEllipse.setWidth(5) x = row['X'] y = row['Y'] # self.AllData[allDataI].append(x) #self.AllData[allDataI].append(y) #if lastX is not None or lastY is not None: self.painter.setPen(penLine) #Point1 = QPoint(lastX, lastY) #Point2 = QPoint(float(x), float(y)) #self.painter.drawLine(Point1, Point2) self.painter.setPen(penEllipse) penLine = QPen(QColor(Qt.red)) self.painter.setBrush(QColor(Qt.white)) if row['popularity_mean'] > 0: CircleSize = (RADIUS / 100) * row['popularity_mean'] + ADDITIONAL else: CircleSize = 10 #print(CircleSize) #if n == 8 and i>=11 and i<=12: self.painter.drawEllipse( float(x) - CircleSize, float(y) - CircleSize, CircleSize * 2, CircleSize * 2) QApplication.processEvents() #sleep(1) self.timer.start(1000 / UPDATE_SPEED) self.overlay.save('Picture Of Map.jpg', format='jpeg') def closeEvent(self, event): #self.FileSaving(self.arr_points, FILE_NAME) sys.exit() #Programm Closing def initUI(self): self.Colors = [ QColor(228, 37, 24), #1 QColor(75, 175, 79), #2 QColor(5, 114, 185), #3 QColor(36, 188, 239), #4 QColor(146, 82, 51), #5 QColor(239, 128, 39), #6 QColor(148, 63, 144), #7 QColor(255, 209, 30), #8 QColor(173, 172, 172), #9 QColor(185, 206, 31), #10 QColor(134, 204, 206), #11 QColor(186, 200, 232), #12 QColor(68, 143, 201), #13 QColor(232, 68, 57), #14 ] self.showMaximized() #self.showNormal() self.setStyleSheet("background-color: white;") self.toolTipWidget = QLabel() self.toolTipWidget.setStyleSheet("QLabel {" "border-style: solid;" "border-width: 1px;" "border-color: grey; " "border-radius: 3px;" "padding: 5px 5px 5px 5px;" "background-color: rgb(255,255,225);" "}") self.toolTipWidget.setWindowFlags(Qt.ToolTip) self.toolTipWidget.setAttribute(Qt.WA_TransparentForMouseEvents) self.toolTipWidget.hide() self.interest = None self.arr_points = [] self.stationSize = [] self.LastAngle = 0 self.timer = QTimer() #Timer init self.timer.timeout.connect(self.update) # Timer init self.setWindowTitle('Moscow Metro Map Poppularity') # Title self.point = None self.DeltaX = 0 self.DeltaY = 0 self.SelfHeight = self.frameGeometry().height() self.LastMousePosition = QPoint(0, 0) self.overlay = QImage() #self.overlay.load('Moscow Metro Map Stations popularity_meanarity\\MainMap.bmp') self.overlay.load(FILE_BACKGROUND) pen = QPen(QColor(Qt.red)) pen.setWidth(5) self.painter = QPainter(self.overlay) self.painter.setPen(pen) self.painter.Antialiasing = False self.timer.start(1000 / UPDATE_SPEED) #self.AllData = self.FileReading(FILE_DATA_NAME) self.AllData = pd.read_csv(FILE_DATA_NAME, ',', encoding='utf-8-sig') #self.WithDates = pd.read_csv(FILE_DATES_NAME,',', encoding='utf-8-sig') #print(self.WithDates) # self.AllData = [x for x in self.AllData.iterrows() if x['Line']='8A'] #self.arr_points = self.FileReading() # self.FileDrawing() def paintEvent(self, event): painter = QPainter() painter.begin(self) #windowsWidth = self.frameGeometry().width() windowsHeight = self.frameGeometry().height() img = self.overlay.scaledToHeight(self.SelfHeight, 0) painter.drawImage(self.DeltaX, self.DeltaY, img) painter.end() del painter def mouseMoveEvent(self, event): CurentPos = event.pos() self.DeltaX -= self.LastMousePosition.x() - CurentPos.x() self.DeltaY -= self.LastMousePosition.y() - CurentPos.y() #self.LastMousePosition = mousePoint self.LastMousePosition = event.pos() def wheelEvent(self, event): #print(str(event.angleDelta())) self.SelfHeight += (event.angleDelta().y()) / 10 self.LastAngle = event.angleDelta().y() def resizeEvent(self, event): self.SelfHeight = self.frameGeometry().height() - 10 if hasattr(self, 'overlay'): img = self.overlay.scaledToHeight(self.SelfHeight, 0) self.DeltaX = (self.frameGeometry().width() - img.width()) / 2 self.DeltaY = 0
class OpenGLWidget(QOpenGLWidget): def __init__(self, parent, radius, quality): QOpenGLWidget.__init__(self, parent) self.__radius = radius self.__quality = quality self.__xRotation = 0 self.__yRotation = 0 self.__zRotation = 0 self.__lastPoint = QPoint() def sizeHint(self): return SIZE def minimumSizeHint(self): return MINIMUM_SIZE def initializeGL(self): glClearColor(0.0, 0.0, 0.0, 0.0) glEnable(GL_DEPTH_TEST) glShadeModel(GL_FLAT) glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) glLightfv(GL_LIGHT0, GL_POSITION, FIRST_LIGHT_POSITION) glEnable(GL_LIGHT1) glLightfv(GL_LIGHT1, GL_POSITION, SECOND_LIGHT_POSITION) def paintGL(self): glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) glLoadIdentity() glTranslatef(0.0, 0.0, -5.0) glRotatef(self.__xRotation / ROTATION_SPEED, 1.0, 0.0, 0.0) glRotatef(self.__yRotation / ROTATION_SPEED, 0.0, 1.0, 0.0) glRotatef(self.__zRotation / ROTATION_SPEED, 0.0, 0.0, 1.0) self.draw() def resizeGL(self, width, height): glMatrixMode(GL_PROJECTION) glLoadIdentity() aspect = width / height if aspect > 1: glOrtho(-DISTANCE * aspect, DISTANCE * aspect, -DISTANCE, DISTANCE, 1, 16) else: glOrtho(-DISTANCE, DISTANCE, -DISTANCE / aspect, DISTANCE / aspect, 1, 16) glMatrixMode(GL_MODELVIEW) def mousePressEvent(self, _event): self.__lastPoint = _event.pos() def mouseMoveEvent(self, _event): dx = _event.x() - self.__lastPoint.x() dy = _event.y() - self.__lastPoint.y() if _event.buttons() & Qt.LeftButton or _event.buttons & Qt.RightButton: self.set_xRotation(self.__xRotation + dy) self.set_yRotation(self.__yRotation + dx) def set_quality(self, quality): self.__quality = quality self.update() def set_radius(self, radius): self.__radius = radius self.update() def normalize_angle(self, angle): while angle < 0: angle += 360 while angle > 360: angle -= 360 def set_xRotation(self, angle): self.normalize_angle(angle) if angle != self.__xRotation: self.__xRotation = angle self.update() def set_yRotation(self, angle): self.normalize_angle(angle) if angle != self.__yRotation: self.__yRotation = angle self.update() def set_zRotation(self, angle): self.normalize_angle(angle) if angle != self.__zRotation: self.__zRotation = angle self.update() def draw(self): radius = self.__radius quality = self.__quality y_multiplier = pi / quality x_multiplier = 2.0 * y_multiplier glPolygonMode(GL_FRONT, GL_FILL) glBegin(GL_QUAD_STRIP) for y_index in range(quality): # theta is the latitude, ranging from 0 to pi theta = y_index * y_multiplier tex_Y = y_index / quality for x_index in range(quality): # phi is the longitude, ranging from 0 to 2*pi phi = x_index * x_multiplier tex_X = x_index / quality x = radius * sin(theta) * cos(phi) y = radius * sin(theta) * sin(phi) z = radius * cos(theta) glNormal3f(x, y, z) glTexCoord2f(tex_X, tex_Y) glVertex3f(x, y, z) theta_new = theta + y_multiplier x = radius * sin(theta_new) * cos(phi) y = radius * sin(theta_new) * sin(phi) z = radius * cos(theta_new) glNormal3f(x, y, z) glTexCoord2f(tex_X, tex_Y + 1 / self.__quality) glVertex3f(x, y, z) glEnd()
def initUI(self): self.Colors = [ QColor(228, 37, 24), #1 QColor(75, 175, 79), #2 QColor(5, 114, 185), #3 QColor(36, 188, 239), #4 QColor(146, 82, 51), #5 QColor(239, 128, 39), #6 QColor(148, 63, 144), #7 QColor(255, 209, 30), #8 QColor(173, 172, 172), #9 QColor(185, 206, 31), #10 QColor(134, 204, 206), #11 QColor(186, 200, 232), #12 QColor(68, 143, 201), #13 QColor(232, 68, 57), #14 ] self.showMaximized() #self.showNormal() self.setStyleSheet("background-color: white;") self.toolTipWidget = QLabel() self.toolTipWidget.setStyleSheet("QLabel {" "border-style: solid;" "border-width: 1px;" "border-color: grey; " "border-radius: 3px;" "padding: 5px 5px 5px 5px;" "background-color: rgb(255,255,225);" "}") self.toolTipWidget.setWindowFlags(Qt.ToolTip) self.toolTipWidget.setAttribute(Qt.WA_TransparentForMouseEvents) self.toolTipWidget.hide() self.interest = None self.arr_points = [] self.stationSize = [] self.LastAngle = 0 self.timer = QTimer() #Timer init self.timer.timeout.connect(self.update) # Timer init self.setWindowTitle('Moscow Metro Map Poppularity') # Title self.point = None self.DeltaX = 0 self.DeltaY = 0 self.SelfHeight = self.frameGeometry().height() self.LastMousePosition = QPoint(0, 0) self.overlay = QImage() #self.overlay.load('Moscow Metro Map Stations popularity_meanarity\\MainMap.bmp') self.overlay.load(FILE_BACKGROUND) pen = QPen(QColor(Qt.red)) pen.setWidth(5) self.painter = QPainter(self.overlay) self.painter.setPen(pen) self.painter.Antialiasing = False self.timer.start(1000 / UPDATE_SPEED) #self.AllData = self.FileReading(FILE_DATA_NAME) self.AllData = pd.read_csv(FILE_DATA_NAME, ',', encoding='utf-8-sig')
def draw_frames(self, qp): qp.setBackgroundMode(Qt.OpaqueMode) black_pen = QtGui.QPen(QtGui.QColor(0, 0, 0)) white_pen = QtGui.QPen(QtGui.QColor(255, 255, 255)) grey_pen = QtGui.QPen(QtGui.QColor("gray")) for sequence in self.animation_data.selected: i = 0 for frame in sequence.frames: # Draw frame border # REPEAT 1 pos = self.sheet2view(frame.topLeft()) size = QSize(round(frame.width() * self.scale), round(frame.height() * self.scale)) qp.setPen(white_pen) qp.setBackground(QtGui.QBrush(QtGui.QColor(0, 0, 0))) #qp.drawText(pos.x(), pos.y() - 2, "POS(%s, %s) SIZE(%s, %s)" % (frame.x(), frame.y(), frame.width(), frame.height())) qp.drawText(pos.x() + 1, pos.y() + 12, str(i)) qp.drawText( pos.x() + 1, pos.y() + size.height() + 12, "WIDTH: %s HEIGHT: %s" % (frame.width(), frame.height()) ) qp.setPen(black_pen) qp.setBackground(QtGui.QBrush(QtGui.QColor(255, 255, 255))) # Draw frame border qp.setBackgroundMode(Qt.TransparentMode) qp.drawRect(pos.x(), pos.y(), size.width(), size.height()) # Rect qp.setBackgroundMode(Qt.OpaqueMode) # Highlight the selected frames if self.mode == ViewerMode.ALTER_SELECTION: # REPEAT 3 a_pos = self.sheet2view(frame.topLeft()) a_size = QSize(round(frame.width() * self.scale), round(frame.height() * self.scale)) if frame in sequence.selected: if frame == sequence.active_frame: colour = QtGui.QColor(180, 215, 255, 100) qp.drawText(a_pos.x(), a_pos.y() - 10, "ACTIVE") else: colour = QtGui.QColor(255, 255, 0, 100) qp.drawText(a_pos.x(), a_pos.y() - 10, "SELECTED") qp.fillRect(a_pos.x() + 1, a_pos.y() + 1, a_size.width() - 1, a_size.height() - 1, colour) i += 1 if self.mode == ViewerMode.ALTER_SELECTION: a_frame = self.animation_data.active_frame mods = QtWidgets.QApplication.keyboardModifiers() if mods & Qt.ControlModifier: shift = self.sheet2view( QPoint( a_frame.x() + a_frame.shift.x(), a_frame.y() + a_frame.shift.y() ) ) circle_radius = 5 qp.drawEllipse( shift.x() - circle_radius, shift.y() - circle_radius, circle_radius * 2, circle_radius * 2 ) qp.drawLine( shift.x(), shift.y() + 4, shift.x(), shift.y() - 4 ) qp.drawLine( shift.x() + 4, shift.y(), shift.x() - 4, shift.y() ) else: self.draw_sizing_handles(qp)
class ShapedClock(QWidget): hourHand = QPolygon([QPoint(7, 8), QPoint(-7, 8), QPoint(0, -40)]) minuteHand = QPolygon([QPoint(7, 8), QPoint(-7, 8), QPoint(0, -70)]) hourColor = QColor(127, 0, 127) minuteColor = QColor(0, 127, 127, 191) def __init__(self, parent=None): super(ShapedClock, self).__init__(parent, Qt.FramelessWindowHint | Qt.WindowSystemMenuHint) timer = QTimer(self) timer.timeout.connect(self.update) timer.start(1000) quitAction = QAction("E&xit", self, shortcut="Ctrl+Q", triggered=QApplication.instance().quit) self.addAction(quitAction) self.setContextMenuPolicy(Qt.ActionsContextMenu) self.setToolTip("Drag the clock with the left mouse button.\n" "Use the right mouse button to open a context menu.") self.setWindowTitle(self.tr("Shaped Analog Clock")) def mousePressEvent(self, event): if event.button() == Qt.LeftButton: self.dragPosition = event.globalPos() - self.frameGeometry( ).topLeft() event.accept() def mouseMoveEvent(self, event): if event.buttons() == Qt.LeftButton: self.move(event.globalPos() - self.dragPosition) event.accept() def paintEvent(self, event): side = min(self.width(), self.height()) time = QTime.currentTime() painter = QPainter(self) painter.setRenderHint(QPainter.Antialiasing) painter.translate(self.width() / 2, self.height() / 2) painter.scale(side / 200.0, side / 200.0) painter.setPen(Qt.NoPen) painter.setBrush(ShapedClock.hourColor) painter.save() painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0))) painter.drawConvexPolygon(ShapedClock.hourHand) painter.restore() painter.setPen(ShapedClock.hourColor) for i in range(12): painter.drawLine(88, 0, 96, 0) painter.rotate(30.0) painter.setPen(Qt.NoPen) painter.setBrush(ShapedClock.minuteColor) painter.save() painter.rotate(6.0 * (time.minute() + time.second() / 60.0)) painter.drawConvexPolygon(ShapedClock.minuteHand) painter.restore() painter.setPen(ShapedClock.minuteColor) for j in range(60): if (j % 5) != 0: painter.drawLine(92, 0, 96, 0) painter.rotate(6.0) def resizeEvent(self, event): side = min(self.width(), self.height()) maskedRegion = QRegion(self.width() / 2 - side / 2, self.height() / 2 - side / 2, side, side, QRegion.Ellipse) self.setMask(maskedRegion) def sizeHint(self): return QSize(100, 100)