Пример #1
0
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
Пример #2
0
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 draw_item(self, face, painter):
        is_draw = True
        if self.is_clipping:
            is_draw = self.sphere.is_face_visible(face)
        if is_draw:
            polygon = QPolygon()
            for index, point_index in enumerate(face):
                p1_x = int(self.sphere.geom.points[face[index-1]][0])
                p1_y = int(self.sphere.geom.points[face[index-1]][1])
                p1_z = int(self.sphere.geom.points[face[index-1]][2])

                p2_x = int(self.sphere.geom.points[point_index][0])
                p2_y = int(self.sphere.geom.points[point_index][1])
                p2_z = int(self.sphere.geom.points[point_index][2])

                if self.sphere.projection_name == "front":
                    # Фронтальная проекция (вид спереди) -> z = 0
                    real_p1 = QPoint(p1_x, p1_y)
                    real_p2 = QPoint(p2_x, p2_y)
                elif self.sphere.projection_name == "horizontal":
                    # Горизонтальная проекция (вид сверху) -> y = 0
                    real_p1 = QPoint(p1_x, p1_z)
                    real_p2 = QPoint(p2_x, p2_z)
                elif self.sphere.projection_name == "profile":
                    # Профильная проекция (вид сбоку) -> x = 0
                    real_p1 = QPoint(p1_y, p1_z)
                    real_p2 = QPoint(p2_y, p2_z)
                else:
                    real_p1 = QPoint(p1_x, p1_y)
                    real_p2 = QPoint(p2_x, p2_y)

                # Точки для проволочного рисования
                real_p1.setX(self.width()/2 + real_p1.x())
                real_p1.setY(self.height()/2 - real_p1.y())
                real_p2.setX(self.width()/2 + real_p2.x())
                real_p2.setY(self.height()/2 - real_p2.y())

                # Полигоны для рисования с цветом
                polygon.append(real_p1)
                polygon.append(real_p2)

                if not self.is_light:
                    painter.drawLine(real_p1, real_p2)

            if self.is_light:

                painter.setBrush(self.sphere.get_face_light(face, self.faces_color))
                painter.drawPolygon(polygon)
Пример #4
0
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 {}
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)
Пример #6
0
    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
Пример #7
0
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()
Пример #8
0
 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
Пример #9
0
    def kineticMove(self, oldx, oldy, newx, newy ):
        """Start a kinetic move from (oldx, oldy) to (newx, newy)"""
        if newx == oldx and newy == oldy:
            return
        
        speed = QPoint(0,0)
        # solve speed*(speed+1)/2 = delta to ensure 1+2+3+...+speed is as close as possible under delta..
        speed.setX((sqrt(1+8*abs(newx-oldx))-1)/2)
        speed.setY((sqrt(1+8*abs(newy-oldy))-1)/2)
        
        # compute the amount of displacement still needed because we're dealing with integer values.
        diff = QPoint(0,0)
        diff.setX((speed.x() * (speed.x() + 1) // 2) - abs(newx - oldx))
        diff.setY((speed.y() * (speed.y() + 1) // 2) - abs(newy - oldy))

        # Since this function is called for exact moves (not free scrolling)
        # limit the kinetic time to 2 seconds, which means 100 ticks, 5050 pixels.
        if speed.y() > 100:
            speed.setY(100)
            diff.setY(-abs(newy-oldy) + 5050)
            
        # Although it is less likely to go beyond that limit for horizontal scrolling,
        # do it for x as well.
        if speed.x() > 100:
            speed.setX(100)
            diff.setX(-abs(newx-oldx) + 5050)
        
        # move left or right, up or down
        if newx > oldx :
            speed.setX(-speed.x())
            diff.setX(-diff.x())
        if newy > oldy :
            speed.setY(-speed.y())
            diff.setY(-diff.y())
        
        # move immediately by the step that cannot be handled by kinetic scrolling.
        # By construction that step is smaller that the initial speed value.
        self.fastScrollBy(diff)
        
        self.kineticStart(speed)
Пример #10
0
	def wave(self):
			   
#		print(points[0][0] ,'<', points[1][0], 'and', points[0][1], '>', points[1][1])

		t = self.machine.getTransition(self.t_active)
		init = QPoint(t.getOrig()[0], t.getOrig()[1])
		end = QPoint(t.getDest()[0], t.getDest()[1])
		angle = t.getAngle()
		print('processing transition', t.id, t.orig, t.dest)
		while t.isActive():
			self.pts = [[init.x(), init.y()], [end.x(), end.y()]]
			if self.pts[0][0] <= self.pts[1][0] and self.pts[0][1] >= self.pts[1][1]:
				while self.pts[0][0] <= self.pts[1][0] and self.pts[0][1] >= self.pts[1][1]:
					self.sumPoint(angle)
			elif self.pts[0][0] <= self.pts[1][0] and self.pts[0][1] <= self.pts[1][1]:
				while self.pts[0][0] <= self.pts[1][0] and self.pts[0][1] <= self.pts[1][1]:
					self.sumPoint(angle)
			elif self.pts[0][0] >= self.pts[1][0] and self.pts[0][1] >= self.pts[1][1]:
				while self.pts[0][0] >= self.pts[1][0] and self.pts[0][1] >= self.pts[1][1]:
					self.sumPoint(angle)
			elif self.pts[0][0] >= self.pts[1][0] and self.pts[0][1] <= self.pts[1][1]:
				while self.pts[0][0] >= self.pts[1][0] and self.pts[0][1] <= self.pts[1][1]:
					self.sumPoint(angle)
Пример #11
0
	def wave(self):
		
		t = self.machine.getActiveTransition()
		if t != None:

			init = QPoint(t.getOrig()[0], t.getOrig()[1])
			end = QPoint(t.getDest()[0], t.getDest()[1])
			angle = t.getAngle()
			#print('processing transition', t.id, t.orig, t.dest)
			while t.isActive():
			#for i in range(3):	#for testing
				self.pts = [[init.x(), init.y()], [end.x(), end.y()]]
				if self.pts[0][0] <= self.pts[1][0] and self.pts[0][1] >= self.pts[1][1]:
					while self.pts[0][0] <= self.pts[1][0] and self.pts[0][1] >= self.pts[1][1]:
						self.sumPoint(angle)
				elif self.pts[0][0] <= self.pts[1][0] and self.pts[0][1] <= self.pts[1][1]:
					while self.pts[0][0] <= self.pts[1][0] and self.pts[0][1] <= self.pts[1][1]:
						self.sumPoint(angle)
				elif self.pts[0][0] >= self.pts[1][0] and self.pts[0][1] >= self.pts[1][1]:
					while self.pts[0][0] >= self.pts[1][0] and self.pts[0][1] >= self.pts[1][1]:
						self.sumPoint(angle)
				elif self.pts[0][0] >= self.pts[1][0] and self.pts[0][1] <= self.pts[1][1]:
					while self.pts[0][0] >= self.pts[1][0] and self.pts[0][1] <= self.pts[1][1]:
						self.sumPoint(angle)
Пример #12
0
 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()
Пример #13
0
 def enemyClick(self, enemy):
     # Opens an info screen on the enemy
     if self.parent.gameover == False and enemy.isDead == False:
     
         if self.parent.isTowerSelected == False:
             # self.statusBarMessage("Enemy clicked")
             self.enemyPopUp = QFrame()
             self.enemyPopUp.setGeometry(500, 500, 100, 100)
         
             grid = QGridLayout()
             self.enemyPopUp.setLayout(grid)
         
             enemyStats = QLabel("Enemy Stats")
             name = QLabel("Name: " + str(enemy.name))
             speed = QLabel("Speed: " + str(enemy.speed))
             health = QLabel("Health: {:.0f}".format(enemy.health))
             pixmap = QLabel()
             pixmap.setPixmap(enemy.picture)
         
             vbox = QVBoxLayout()
             vbox.addWidget(enemyStats)
             vbox.addWidget(name)
             vbox.addWidget(speed)
             vbox.addWidget(health)
 
             grid.addLayout(vbox, 0, 0)
         
             vbox2 = QVBoxLayout()
             vbox2.addWidget(pixmap)
             vbox2.addStretch()
             
             doneButton = QPushButton("Done")
             vbox2.addWidget(doneButton)
             grid.addLayout(vbox2, 0, 1)
             
             location = QPoint(QCursor.pos())
             self.enemyPopUp.move(location.x() - 100, location.y())
             self.enemyPopUp.show()
             doneButton.clicked.connect(self.enemyPopUp.hide)
     
     elif self.parent.gameover == True:
         self.statusBarMessage("The game has ended. Stop doing stuff.")
Пример #14
0
    def download(self):
        grab = None
        for x in range(self._tilesRect.width()):
            for y in range(self._tilesRect.height()):
                tp = Point(self._tilesRect.topLeft() + QPoint(x, y))
                if tp not in self._tilePixmaps:
                    grab = QPoint(tp)
                    break

        if grab is None:
            self._url = QUrl()
            return

        path = 'http://tile.openstreetmap.org/%d/%d/%d.png' % (self.zoom, grab.x(), grab.y())
        self._url = QUrl(path)
        request = QNetworkRequest()
        request.setUrl(self._url)
        request.setRawHeader(b'User-Agent', b'Nokia (PyQt) Graphics Dojo 1.0')
        request.setAttribute(QNetworkRequest.User, grab)
        self._manager.get(request)
Пример #15
0
    def mouseMoveEvent(self, event):
        if event.buttons() == Qt.RightButton:
            # write the relative cursor position to mime data
            mimeData = QMimeData()
            # simple string with 'x,y'
            mimeData.setText('%d,%d' % (event.x(), event.y()))

            # let's make it fancy. we'll show a "ghost" of the button as we drag
            # grab the button to a pixmap
            pixmap = self.grab()

            # below makes the pixmap half transparent
            painter = QPainter(pixmap)
            painter.setCompositionMode(painter.CompositionMode_DestinationIn)
            painter.fillRect(pixmap.rect(), QColor(0, 0, 0, 127))
            painter.end()

            # make a QDrag
            drag = QDrag(self)
            # put our MimeData
            drag.setMimeData(mimeData)
            # set its Pixmap
            drag.setPixmap(pixmap)
            # shift the Pixmap so that it coincides with the cursor position
            drag.setHotSpot(event.pos())

            # start the drag operation
            # exec_ will return the accepted action from dropEvent
            if drag.exec_(Qt.CopyAction | Qt.MoveAction) == Qt.MoveAction:
                print('moved')
            else:
                print('copied:'+str(event.globalPos()))
                #self.move(event.pos())

        elif event.buttons() == Qt.LeftButton:
            delta = QPoint(event.globalPos() - self.oldPos)
            self.move(self.frameGeometry().x() + delta.x(), self.frameGeometry().y() + delta.y())
            self.oldPos = event.globalPos()
Пример #16
0
class SlippyMap(QObject):

    updated = pyqtSignal(QRect)

    def __init__(self, parent=None):
        super(SlippyMap, self).__init__(parent)

        self._offset = QPoint()
        self._tilesRect = QRect()
        self._tilePixmaps = {} # Point(x, y) to QPixmap mapping
        self._manager = QNetworkAccessManager()
        self._url = QUrl()
        # public vars
        self.width = 400
        self.height = 300
        self.zoom = 15
        self.latitude = 59.9138204
        self.longitude = 10.7387413

        self._emptyTile = QPixmap(TDIM, TDIM)
        self._emptyTile.fill(Qt.lightGray)

        cache = QNetworkDiskCache()
        cache.setCacheDirectory(
            QStandardPaths.writableLocation(QStandardPaths.CacheLocation))
        self._manager.setCache(cache)
        self._manager.finished.connect(self.handleNetworkData)

    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 render(self, p, rect):
        for x in range(self._tilesRect.width()):
            for y in range(self._tilesRect.height()):
                tp = Point(x + self._tilesRect.left(), y + self._tilesRect.top())
                box = self.tileRect(tp)
                if rect.intersects(box):
                    p.drawPixmap(box, self._tilePixmaps.get(tp, self._emptyTile))
   
    def pan(self, delta):
        dx = QPointF(delta) / float(TDIM)
        center = tileForCoordinate(self.latitude, self.longitude, self.zoom) - dx
        self.latitude = latitudeFromTile(center.y(), self.zoom)
        self.longitude = longitudeFromTile(center.x(), self.zoom)
        self.invalidate()

    # slots
    def handleNetworkData(self, reply):
        img = QImage()
        tp = Point(reply.request().attribute(QNetworkRequest.User))
        url = reply.url()
        if not reply.error():
            if img.load(reply, None):
                self._tilePixmaps[tp] = QPixmap.fromImage(img)
        reply.deleteLater()
        self.updated.emit(self.tileRect(tp))

        # purge unused tiles
        bound = self._tilesRect.adjusted(-2, -2, 2, 2)
        for tp in list(self._tilePixmaps.keys()):
            if not bound.contains(tp):
                del self._tilePixmaps[tp]
        self.download()

    def download(self):
        grab = None
        for x in range(self._tilesRect.width()):
            for y in range(self._tilesRect.height()):
                tp = Point(self._tilesRect.topLeft() + QPoint(x, y))
                if tp not in self._tilePixmaps:
                    grab = QPoint(tp)
                    break

        if grab is None:
            self._url = QUrl()
            return

        path = 'http://tile.openstreetmap.org/%d/%d/%d.png' % (self.zoom, grab.x(), grab.y())
        self._url = QUrl(path)
        request = QNetworkRequest()
        request.setUrl(self._url)
        request.setRawHeader(b'User-Agent', b'Nokia (PyQt) Graphics Dojo 1.0')
        request.setAttribute(QNetworkRequest.User, grab)
        self._manager.get(request)

    def tileRect(self, tp):
        t = tp - self._tilesRect.topLeft()
        x = t.x() * TDIM + self._offset.x()
        y = t.y() * TDIM + self._offset.y()

        return QRect(x, y, TDIM, TDIM)
Пример #17
0
    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()
Пример #18
0
 def move(self, a0: QtCore.QPoint):
     super().move(a0.x() - 15, a0.y() - 15)
Пример #19
0
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
    toolTipWidget: QLabel

    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 + R
            stationsName = self.FileReading(FILE_STATIONS_NAME)
            self.FileSaving(self.GetGoogleData(stationsName), FILE_DATA_NAME)

    def GetStationPopularity(self, station_name, trends_object):
        kw_list = station_name
        trends_object.build_payload(kw_list,
                                    cat=0,
                                    timeframe='today 5-y',
                                    geo='',
                                    gprop='')

        interest = trends_object.interest_over_time()
        return interest.mean()[0]
        #plt.plot(interest[station_name])
        #plt.show()

    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')
            self.toolTipWidget.setText(' testtestetstetstestete ')
            self.toolTipWidget.move(event.pos())
            #self.toolTipWidget.adjustSize()
            self.toolTipWidget.show()

        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([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, fileName: str):
        penLine = QPen(QColor(Qt.red))
        penLine.setWidth(10)

        #my_file = Path('!StationsLine12.txt')
        #print(my_file.isfile())

        allDataI = 0
        for n in range(14 * 2):
            penEllipse = QPen(self.Colors[int(n / 2)])
            penEllipse.setWidth(5)

            data = []
            path = fileName + str(n / 2 + 1) + '.txt'
            my_file = Path(path)
            #print(os.listdir())

            if my_file.is_file():
                with open(fileName + str(n / 2 + 1) + '.txt', 'r') as f:
                    data = f.read().split('\n')
                    f.close()

                lastX = None
                lastY = None
                Point1 = None
                Point2 = None
                Startlen = None
                x = 0
                y = 0
                i = 0
                #print(self.NameReading('!Stations.txt'))
                for line in data:
                    x, y = line.split(';')
                    # 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))

                    # CircleSize = (RADIUS/100) * float(self.AllData[i][1]) + ADDITIONAL
                    CircleSize = 20
                    #print(CircleSize)
                    #if n == 8 and i>=11 and i<=12:
                    self.painter.drawEllipse(
                        float(x) - CircleSize,
                        float(y) - CircleSize, CircleSize * 2, CircleSize * 2)
                    i += 1
                    allDataI += 1

    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.pytrends = TrendReq(hl='en-US', tz=360)

        self.showMaximized()
        #self.showNormal()
        self.setStyleSheet("background-color: white;")

        self.toolTipWidget = QLabel()
        #        self.toolTipWidget.setFrameShape(QFrame.StyleSheet)
        self.toolTipWidget.setStyleSheet("background-color: rgb(255,255,225);")
        self.toolTipWidget.setWindowFlags(Qt.ToolTip)
        self.toolTipWidget.setAttribute(Qt.WA_TransparentForMouseEvents)
        self.toolTipWidget.hide()

        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\\MainMap.bmp')

        pen = QPen(QColor(Qt.red))
        pen.setWidth(5)
        self.painter = QPainter(self.overlay)
        self.painter.setPen(pen)
        self.painter.Antialiasing = True

        self.timer.start(1000 / 50)  #50 кадров в секунду

        #self.AllData = self.FileReading(FILE_DATA_NAME)
        self.AllData = pd.read_csv(FILE_DATA_NAME)
        #self.arr_points = self.FileReading()
        self.FileDrawing(FILE_NAME)

    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
Пример #20
0
class Compass(QWidget):
    angle_event = pyqtSignal(Angle)

    def __init__(self, parent=None):
        super().__init__(parent)
        self.offset = 75
        self.span = self.offset + 525
        self.center = QPoint(self.span / 2, self.span / 2)
        self.setMinimumSize(self.span, self.span)
        self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Maximum)
        self.setMouseTracking(True)

        self.wedges = []
        for start in range(0, 360 * 16, 45 * 16):
            self.wedges.append(
                CompassWedge(
                    start, self.span, self.span, self.offset,
                    Angle(floor(((360 - start / 16 + 45) % 360) / 45)), self))

        deg_font = QFont("Consolas", 22, 2)
        for deg in range(8):
            temp = QLabel(self)
            angle = deg * 45
            temp.setText(str(angle) + '°')
            temp.setFont(deg_font)
            tw = temp.fontMetrics().boundingRect(temp.text()).width()
            th = temp.fontMetrics().boundingRect(temp.text()).height()
            temp.move(self.deg_lbl_pos((180 - angle) % 360, QSize(tw, th)))

    def deg_lbl_pos(self, angle, size):
        x_0 = self.center.x()
        y_0 = self.center.y()
        size_x = size.width()
        size_y = size.height()
        off_x = 0
        off_y = 0
        dist = self.span / 2 - self.offset + 10
        if angle == 0:
            off_x = -size_x / 2
        elif angle == 90:
            off_y = -size_y / 2
        elif angle == 135:
            off_y = -size_y
        elif angle == 180:
            off_x = -size_x / 2
            off_y = -size_y
        elif angle == 225:
            off_y = -size_y
            off_x = -size_x
        elif angle == 270:
            off_y = -size_y / 2
            off_x = -size_x
        elif angle == 315:
            off_x = -size_x

        theta_rad = pi / 2 - radians(angle)
        return QPoint(round(x_0 + dist * cos(theta_rad) + off_x),
                      round(y_0 + dist * sin(theta_rad) + off_y))

    def mouseMoveEvent(self, event):
        x_1 = event.pos().x()
        y_1 = event.pos().y()
        x_2 = self.center.x()
        y_2 = self.center.y()
        dist = floor(hypot(x_2 - x_1, y_2 - y_1))
        angle = atan2(x_2 - x_1, y_2 - y_1)
        if dist <= floor(self.span / 2) - self.offset:
            if 0 <= angle < (2 * pi) / 8:
                self.activate_wedge(2)
            elif (2 * pi) / 8 <= angle < 2 * (2 * pi) / 8:
                self.activate_wedge(3)
            elif 2 * (2 * pi) / 8 <= angle < 3 * (2 * pi) / 8:
                self.activate_wedge(4)
            elif 3 * (2 * pi) / 8 <= angle < 4 * (2 * pi) / 8:
                self.activate_wedge(5)
            elif 0 > angle >= -(2 * pi) / 8:
                self.activate_wedge(1)
            elif -(2 * pi) / 8 > angle >= -2 * (2 * pi) / 8:
                self.activate_wedge(0)
            elif -2 * (2 * pi) / 8 > angle >= -3 * (2 * pi) / 8:
                self.activate_wedge(7)
            elif -3 * (2 * pi) / 8 > angle >= -4 * (2 * pi) / 8:
                self.activate_wedge(6)
        else:
            self.activate_wedge(-1)

    def mouseReleaseEvent(self, event):
        for wedge in self.wedges:
            if wedge.active:
                self.angle_event.emit(wedge.id)
                wedge.mark(True)

    def activate_wedge(self, active):
        for index in range(self.wedges.__len__()):
            self.wedges[index].activate(True if index == active else False)

    @pyqtSlot()
    def clear_state(self):
        for wedge in self.wedges:
            wedge.mark(False)
Пример #21
0
class Transect(QtWidgets.QGraphicsScene):

    # Initialisation function  of the class
    def __init__(self, mainWindow, imagetoPaint, dataset, rowS, colS,
                 tabWindow):
        super(Transect, self).__init__()

        #create the canvas to draw the line on and all its necessary components
        self.addItem(QGraphicsPixmapItem(imagetoPaint))
        self.img = imagetoPaint
        self.values = []
        self.distances = []
        self.data = dataset
        self.pixSpacing = rowS / colS
        self._start = QPointF()
        self.drawing = True
        self._current_rect_item = None
        self.pos1 = QPoint()
        self.pos2 = QPoint()
        self.points = []
        self.tabWindow = tabWindow
        self.mainWindow = mainWindow

    # This function starts the line draw when the mouse is pressed into the 2D view of the scan
    def mousePressEvent(self, event):
        # If is the first time we can draw as we want a line per button press
        if self.drawing == True:
            self.pos1 = event.scenePos()
            self._current_rect_item = QtWidgets.QGraphicsLineItem()
            self._current_rect_item.setPen(QtCore.Qt.red)
            self._current_rect_item.setFlag(
                QtWidgets.QGraphicsItem.ItemIsMovable, False)
            self.addItem(self._current_rect_item)
            self._start = event.scenePos()
            r = QtCore.QLineF(self._start, self._start)
            self._current_rect_item.setLine(r)

    # This function tracks the mouse and draws the line from the original press point
    def mouseMoveEvent(self, event):
        if self._current_rect_item is not None and self.drawing == True:
            r = QtCore.QLineF(self._start, event.scenePos())
            self._current_rect_item.setLine(r)

    # This function terminates the line drawing and initiates the plot
    def mouseReleaseEvent(self, event):
        if self.drawing == True:
            self.pos2 = event.scenePos()
            self.drawDDA(round(self.pos1.x()), round(self.pos1.y()),
                         round(self.pos2.x()), round(self.pos2.y()))
            self.drawing = False
            self.plotResult()
            self._current_rect_item = None

    # This function performs the DDA algorithm that locates all the points in the drawn line
    def drawDDA(self, x1, y1, x2, y2):
        x, y = x1, y1
        length = abs(x2 - x1) if abs(x2 - x1) > abs(y2 - y1) else abs(y2 - y1)
        dx = (x2 - x1) / float(length)
        dy = (y2 - y1) / float(length)
        self.points.append((round(x), round(y)))

        for i in range(length):
            x += dx
            y += dy
            self.points.append((round(x), round(y)))

        # get the values of these points from the dataset
        self.getValues()
        # get their distances for the plot
        self.getDistances()

    # This function calculates the distance between two points
    def calculateDistance(self, x1, y1, x2, y2):
        dist = math.sqrt((x2 - x1)**2 + (y2 - y1)**2)
        return dist

    # This function gets the corresponding values of all the points in the drawn line from the dataset
    def getValues(self):
        for i, j in self.points:
            if i in range(512) and j in range(512):
                self.values.append(self.data[i][j])

    # Get the distance of each point from the end of the line
    def getDistances(self):
        for i, j in self.points:
            if i in range(512) and j in range(512):
                self.distances.append(
                    self.calculateDistance(i, j, round(self.pos2.x()),
                                           round(self.pos2.y())))
        self.distances.reverse()

    # This function handles the closing event of the transect graph
    def on_close(self, event):
        plt1.close()
        #returns the main page back to a non-drawing environment
        self.mainWindow.dicom_view.update_view()
        event.canvas.figure.axes[0].has_been_closed = True

    # This function plots the Transect graph into a pop up window
    def plotResult(self):
        plt1.close('all')
        newList = [(x * self.pixSpacing) for x in self.distances]
        # adding a dummy manager
        fig1 = plt1.figure(num='Transect Graph')
        new_manager = fig1.canvas.manager
        new_manager.canvas.figure = fig1
        fig1.set_canvas(new_manager.canvas)
        ax1 = fig1.add_subplot(111)
        ax1.has_been_closed = False
        ax1.step(newList, self.values, where='mid')
        plt1.xlabel('Distance mm')
        plt1.ylabel('CT #')
        plt1.grid(True)
        fig1.canvas.mpl_connect('close_event', self.on_close)
        plt1.show()
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))
Пример #23
0
class GLWidget(QOpenGLWidget):
    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 setXRotation(self, angle):
        angle = self.normalizeAngle(angle)
        if angle != self.xRot:
            self.xRot = angle

    def setYRotation(self, angle):
        angle = self.normalizeAngle(angle)
        if angle != self.yRot:
            self.yRot = angle

    def setZRotation(self, angle):
        angle = self.normalizeAngle(angle)
        if angle != self.zRot:
            self.zRot = angle

    def initializeGL(self):
        # gl = self.context().versionFunctions()
        # gl.initializeOpenGLFunctions()

        self.object = self.makeObject()

    def mousePressEvent(self, event):
        self.lastPos = event.pos()

    def mouseMoveEvent(self, event):
        dx = event.x() - self.lastPos.x()
        dy = event.y() - self.lastPos.y()

        if event.buttons() & Qt.LeftButton:
            self.setXRotation(self.xRot + 8 * dy)
            self.setYRotation(self.yRot + 8 * dx)
        elif event.buttons() & Qt.RightButton:
            self.setXRotation(self.xRot + 8 * dy)
            self.setZRotation(self.zRot + 8 * dx)

        self.lastPos = event.pos()

    def paintEvent(self, event):
        self.makeCurrent()

        gl.glMatrixMode(gl.GL_MODELVIEW)
        gl.glPushMatrix()

        self.setClearColor(self.trolltechPurple.darker())
        gl.glShadeModel(gl.GL_SMOOTH)
        gl.glEnable(gl.GL_DEPTH_TEST)
        #gl.glEnable(gl.GL_CULL_FACE)
        gl.glEnable(gl.GL_LIGHTING)
        gl.glEnable(gl.GL_LIGHT0)
        gl.glEnable(gl.GL_MULTISAMPLE)
        gl.glLightfv(gl.GL_LIGHT0, gl.GL_POSITION, (0.5, 5.0, 7.0, 1.0))

        self.setupViewport(self.width(), self.height())

        gl.glClear(gl.GL_COLOR_BUFFER_BIT | gl.GL_DEPTH_BUFFER_BIT)
        gl.glLoadIdentity()
        gl.glTranslated(0.0, 0.0, -10.0)
        gl.glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0)
        gl.glRotated(self.yRot / 16.0, 0.0, 1.0, 0.0)
        gl.glRotated(self.zRot / 16.0, 0.0, 0.0, 1.0)
        gl.glCallList(self.object)

        gl.glMatrixMode(gl.GL_MODELVIEW)
        gl.glPopMatrix()

        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)

        for bubble in self.bubbles:
            if bubble.rect().intersects(QRectF(event.rect())):
                bubble.drawBubble(painter)

        self.drawInstructions(painter)
        painter.end()

    def resizeGL(self, width, height):
        self.setupViewport(width, height)

    def showEvent(self, event):
        self.createBubbles(20 - len(self.bubbles))

    def sizeHint(self):
        return QSize(400, 400)

    def makeObject(self):
        genList = gl.glGenLists(1)
        gl.glNewList(genList, gl.GL_COMPILE)

        gl.glBegin(gl.GL_QUADS)

        x1 = +0.06
        y1 = -0.14
        x2 = +0.14
        y2 = -0.06
        x3 = +0.08
        y3 = +0.00
        x4 = +0.30
        y4 = +0.22

        self.quad(x1, y1, x2, y2, y2, x2, y1, x1)
        self.quad(x3, y3, x4, y4, y4, x4, y3, x3)

        self.extrude(x1, y1, x2, y2)
        self.extrude(x2, y2, y2, x2)
        self.extrude(y2, x2, y1, x1)
        self.extrude(y1, x1, x1, y1)
        self.extrude(x3, y3, x4, y4)
        self.extrude(x4, y4, y4, x4)
        self.extrude(y4, x4, y3, x3)

        NumSectors = 200

        for i in range(NumSectors):
            angle1 = (i * 2 * math.pi) / NumSectors
            x5 = 0.30 * math.sin(angle1)
            y5 = 0.30 * math.cos(angle1)
            x6 = 0.20 * math.sin(angle1)
            y6 = 0.20 * math.cos(angle1)

            angle2 = ((i + 1) * 2 * math.pi) / NumSectors
            x7 = 0.20 * math.sin(angle2)
            y7 = 0.20 * math.cos(angle2)
            x8 = 0.30 * math.sin(angle2)
            y8 = 0.30 * math.cos(angle2)

            self.quad(x5, y5, x6, y6, x7, y7, x8, y8)

            self.extrude(x6, y6, x7, y7)
            self.extrude(x8, y8, x5, y5)

        gl.glEnd()
        gl.glEndList()

        return genList

    def quad(self, x1, y1, x2, y2, x3, y3, x4, y4):
        gl.glNormal3d(0.0, 0.0, -1.0)
        gl.glVertex3d(x1, y1, -0.05)
        gl.glVertex3d(x2, y2, -0.05)
        gl.glVertex3d(x3, y3, -0.05)
        gl.glVertex3d(x4, y4, -0.05)

        gl.glNormal3d(0.0, 0.0, 1.0)
        gl.glVertex3d(x4, y4, +0.05)
        gl.glVertex3d(x3, y3, +0.05)
        gl.glVertex3d(x2, y2, +0.05)
        gl.glVertex3d(x1, y1, +0.05)

    def extrude(self, x1, y1, x2, y2):
        self.setColor(self.trolltechGreen.darker(250 + int(100 * x1)))

        gl.glNormal3d((x1 + x2) / 2.0, (y1 + y2) / 2.0, 0.0)
        gl.glVertex3d(x1, y1, +0.05)
        gl.glVertex3d(x2, y2, +0.05)
        gl.glVertex3d(x2, y2, -0.05)
        gl.glVertex3d(x1, y1, -0.05)

    def normalizeAngle(self, angle):
        while angle < 0:
            angle += 360 * 16
        while angle > 360 * 16:
            angle -= 360 * 16
        return angle

    def createBubbles(self, number):
        for i in range(number):
            position = QPointF(self.width() * (0.1 + 0.8 * random.random()),
                               self.height() * (0.1 + 0.8 * random.random()))
            radius = min(self.width(),
                         self.height()) * (0.0125 + 0.0875 * random.random())
            velocity = QPointF(
                self.width() * 0.0125 * (-0.5 + random.random()),
                self.height() * 0.0125 * (-0.5 + random.random()))

            self.bubbles.append(Bubble(position, radius, velocity))

    def animate(self):
        for bubble in self.bubbles:
            bubble.move(self.rect())

        self.update()

    def setupViewport(self, width, height):
        side = min(width, height)
        gl.glViewport((width - side) // 2, (height - side) // 2, side, side)

        gl.glMatrixMode(gl.GL_PROJECTION)
        gl.glLoadIdentity()
        gl.glOrtho(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0)
        gl.glMatrixMode(gl.GL_MODELVIEW)

    def drawInstructions(self, painter):
        text = "Click and drag with the left mouse button to rotate the Qt " \
                "logo."
        metrics = QFontMetrics(self.font())
        border = max(4, metrics.leading())

        rect = metrics.boundingRect(0, 0,
                                    self.width() - 2 * border,
                                    int(self.height() * 0.125),
                                    Qt.AlignCenter | Qt.TextWordWrap, text)
        painter.setRenderHint(QPainter.TextAntialiasing)
        painter.fillRect(QRect(0, 0, self.width(),
                               rect.height() + 2 * border),
                         QColor(0, 0, 0, 127))
        painter.setPen(Qt.white)
        painter.fillRect(QRect(0, 0, self.width(),
                               rect.height() + 2 * border),
                         QColor(0, 0, 0, 127))
        painter.drawText(
            (self.width() - rect.width()) / 2, border, rect.width(),
            rect.height(), Qt.AlignCenter | Qt.TextWordWrap, text)

    def setClearColor(self, c):
        gl.glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF())

    def setColor(self, c):
        gl.glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF())
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
Пример #25
0
class MandelbrotWidget(QWidget):
    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 paintEvent(self, event):
        painter = QPainter(self)
        painter.fillRect(self.rect(), Qt.black)

        if self.pixmap.isNull():
            painter.setPen(Qt.white)
            painter.drawText(self.rect(), Qt.AlignCenter,
                             "Rendering initial image, please wait...")
            return

        if self.curScale == self.pixmapScale:
            painter.drawPixmap(self.pixmapOffset, self.pixmap)
        else:
            scaleFactor = self.pixmapScale / self.curScale
            newWidth = int(self.pixmap.width() * scaleFactor)
            newHeight = int(self.pixmap.height() * scaleFactor)
            newX = self.pixmapOffset.x() + (self.pixmap.width() - newWidth) / 2
            newY = self.pixmapOffset.y() + (self.pixmap.height() -
                                            newHeight) / 2

            painter.save()
            painter.translate(newX, newY)
            painter.scale(scaleFactor, scaleFactor)
            exposed, _ = painter.worldTransform().inverted()
            exposed = exposed.mapRect(self.rect()).adjusted(-1, -1, 1, 1)
            painter.drawPixmap(exposed, self.pixmap, exposed)
            painter.restore()

        text = "Use mouse wheel or the '+' and '-' keys to zoom. Press and " \
                "hold left mouse button to scroll."
        metrics = painter.fontMetrics()
        textWidth = metrics.width(text)

        painter.setPen(Qt.NoPen)
        painter.setBrush(QColor(0, 0, 0, 127))
        painter.drawRect((self.width() - textWidth) / 2 - 5, 0, textWidth + 10,
                         metrics.lineSpacing() + 5)
        painter.setPen(Qt.white)
        painter.drawText((self.width() - textWidth) / 2,
                         metrics.leading() + metrics.ascent(), text)

    def resizeEvent(self, event):
        self.thread.render(self.centerX, self.centerY, self.curScale,
                           self.size())

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Plus:
            self.zoom(ZoomInFactor)
        elif event.key() == Qt.Key_Minus:
            self.zoom(ZoomOutFactor)
        elif event.key() == Qt.Key_Left:
            self.scroll(-ScrollStep, 0)
        elif event.key() == Qt.Key_Right:
            self.scroll(+ScrollStep, 0)
        elif event.key() == Qt.Key_Down:
            self.scroll(0, -ScrollStep)
        elif event.key() == Qt.Key_Up:
            self.scroll(0, +ScrollStep)
        else:
            super(MandelbrotWidget, self).keyPressEvent(event)

    def wheelEvent(self, event):
        numDegrees = event.angleDelta().y() / 8
        numSteps = numDegrees / 15.0
        self.zoom(pow(ZoomInFactor, numSteps))

    def mousePressEvent(self, event):
        if event.buttons() == Qt.LeftButton:
            self.lastDragPos = QPoint(event.pos())

    def mouseMoveEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            self.pixmapOffset += event.pos() - self.lastDragPos
            self.lastDragPos = QPoint(event.pos())
            self.update()

    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 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 zoom(self, zoomFactor):
        self.curScale *= zoomFactor
        self.update()
        self.thread.render(self.centerX, self.centerY, self.curScale,
                           self.size())

    def scroll(self, deltaX, deltaY):
        self.centerX += deltaX * self.curScale
        self.centerY += deltaY * self.curScale
        self.update()
        self.thread.render(self.centerX, self.centerY, self.curScale,
                           self.size())
Пример #26
0
    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()
Пример #27
0
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
Пример #28
0
    def _incline_line(self, path: QtGui.QPainterPath, point1: QtCore.QPoint,
                      point2: QtCore.QPoint, span_left: list,
                      span_right: list):
        #绘制站间的斜线
        #TODO 暂未考虑直接跨过无定义区域的情况
        width = self.graphWidget.scene.width() - \
                self.graphWidget.margins["left"] - self.graphWidget.margins["right"]
        if point1.inRange and point2.inRange:
            if point1.x() <= point2.x():
                path.lineTo(point2)
            else:
                # 跨界运行线
                dx = point2.x() - point1.x() + width
                dy = point2.y() - point1.y()
                ax = width + self.graphWidget.margins["left"] - point1.x()
                h = ax * dy / dx
                span_right.append(point1.y() + h)
                span_left.append(point1.y() + h)
                path.lineTo(self.graphWidget.margins["left"] + width,
                            point1.y() + h)
                path.moveTo(self.graphWidget.margins["left"], point1.y() + h)
                path.lineTo(point2)
        elif not point1.inRange and not point2.inRange:
            return

        elif point1.inRange:
            #右侧点越界
            dx = point2.x() - point1.x() + width
            dy = point2.y() - point1.y()
            ax = width + self.graphWidget.margins["left"] - point1.x()
            h = ax * dy / dx
            span_right.append(point1.y() + h)
            path.lineTo(self.graphWidget.margins["left"] + width,
                        point1.y() + h)

        else:
            #左侧点越界
            dx = point2.x() - point1.x() + width
            dy = point2.y() - point1.y()
            ax = width + self.graphWidget.margins["left"] - point1.x()
            h = ax * dy / dx
            span_left.append(point1.y() + h)
            path.moveTo(self.graphWidget.margins["left"], point1.y() + h)
            path.lineTo(point2)
Пример #29
0
class HelloGLWidget(QOpenGLWidget):
    """HelloGLWidget(QOpenGLWidget)

    Provides a custom widget to display an OpenGL-rendered Qt logo.
    Various properties and slots are defined so that the user can rotate
    the logo, and signals are defined to enable other components to
    react to changes to its orientation.
    """

    # We define three signals that are used to indicate changes to the
    # rotation of the logo.
    xRotationChanged = pyqtSignal(int)
    yRotationChanged = pyqtSignal(int)
    zRotationChanged = pyqtSignal(int)

    def __init__(self, parent=None):
        super(HelloGLWidget, self).__init__(parent)

        self.object = 0
        self.xRot = 0
        self.yRot = 0
        self.zRot = 0

        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.setWindowTitle("Hello GL")

    # The rotation of the logo about the x-axis can be controlled using the
    # xRotation property, defined using the following getter and setter
    # methods.

    def getXRotation(self):
        return self.xRot

    # The setXRotation() setter method is also a slot.
    @pyqtSlot(int)
    def setXRotation(self, angle):
        angle = self.normalizeAngle(angle)
        if angle != self.xRot:
            self.xRot = angle
            self.xRotationChanged.emit(angle)
            self.update()

    xRotation = pyqtProperty(int, getXRotation, setXRotation)

    # The rotation of the logo about the y-axis can be controlled using the
    # yRotation property, defined using the following getter and setter
    # methods.

    def getYRotation(self):
        return self.yRot

    # The setYRotation() setter method is also a slot.
    @pyqtSlot(int)
    def setYRotation(self, angle):
        angle = self.normalizeAngle(angle)
        if angle != self.yRot:
            self.yRot = angle
            self.yRotationChanged.emit(angle)
            self.update()

    yRotation = pyqtProperty(int, getYRotation, setYRotation)

    # The rotation of the logo about the z-axis can be controlled using the
    # zRotation property, defined using the following getter and setter
    # methods.

    def getZRotation(self):
        return self.zRot

    # The setZRotation() setter method is also a slot.
    @pyqtSlot(int)
    def setZRotation(self, angle):
        angle = self.normalizeAngle(angle)
        if angle != self.zRot:
            self.zRot = angle
            self.zRotationChanged.emit(angle)
            self.update()

    zRotation = pyqtProperty(int, getZRotation, setZRotation)

    def minimumSizeHint(self):
        return QSize(50, 50)

    def sizeHint(self):
        return QSize(200, 200)

    def initializeGL(self):
        self.gl = self.context().versionFunctions()
        self.gl.initializeOpenGLFunctions()

        self.setClearColor(self.trolltechPurple.darker())
        self.object = self.makeObject()
        self.gl.glShadeModel(self.gl.GL_SMOOTH)
        self.gl.glEnable(self.gl.GL_DEPTH_TEST)
        self.gl.glEnable(self.gl.GL_CULL_FACE)

    def paintGL(self):
        self.gl.glClear(self.gl.GL_COLOR_BUFFER_BIT | self.gl.GL_DEPTH_BUFFER_BIT)
        self.gl.glLoadIdentity()
        self.gl.glTranslated(0.0, 0.0, -10.0)
        self.gl.glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0)
        self.gl.glRotated(self.yRot / 16.0, 0.0, 1.0, 0.0)
        self.gl.glRotated(self.zRot / 16.0, 0.0, 0.0, 1.0)
        self.gl.glCallList(self.object)

    def resizeGL(self, width, height):
        side = min(width, height)
        self.gl.glViewport((width - side) / 2, (height - side) / 2, side, side)

        self.gl.glMatrixMode(self.gl.GL_PROJECTION)
        self.gl.glLoadIdentity()
        self.gl.glOrtho(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0)
        self.gl.glMatrixMode(self.gl.GL_MODELVIEW)

    def mousePressEvent(self, event):
        self.lastPos = QPoint(event.pos())

    def mouseMoveEvent(self, event):
        dx = event.x() - self.lastPos.x()
        dy = event.y() - self.lastPos.y()

        if event.buttons() & Qt.LeftButton:
            self.setXRotation(self.xRot + 8 * dy)
            self.setYRotation(self.yRot + 8 * dx)
        elif event.buttons() & Qt.RightButton:
            self.setXRotation(self.xRot + 8 * dy)
            self.setZRotation(self.zRot + 8 * dx)

        self.lastPos = QPoint(event.pos())

    def makeObject(self):
        genList = self.gl.glGenLists(1)
        self.gl.glNewList(genList, self.gl.GL_COMPILE)

        self.gl.glBegin(self.gl.GL_QUADS)

        x1 = +0.06
        y1 = -0.14
        x2 = +0.14
        y2 = -0.06
        x3 = +0.08
        y3 = +0.00
        x4 = +0.30
        y4 = +0.22

        self.quad(x1, y1, x2, y2, y2, x2, y1, x1)
        self.quad(x3, y3, x4, y4, y4, x4, y3, x3)

        self.extrude(x1, y1, x2, y2)
        self.extrude(x2, y2, y2, x2)
        self.extrude(y2, x2, y1, x1)
        self.extrude(y1, x1, x1, y1)
        self.extrude(x3, y3, x4, y4)
        self.extrude(x4, y4, y4, x4)
        self.extrude(y4, x4, y3, x3)

        Pi = 3.14159265358979323846
        NumSectors = 200

        for i in range(NumSectors):
            angle1 = (i * 2 * Pi) / NumSectors
            x5 = 0.30 * math.sin(angle1)
            y5 = 0.30 * math.cos(angle1)
            x6 = 0.20 * math.sin(angle1)
            y6 = 0.20 * math.cos(angle1)

            angle2 = ((i + 1) * 2 * Pi) / NumSectors
            x7 = 0.20 * math.sin(angle2)
            y7 = 0.20 * math.cos(angle2)
            x8 = 0.30 * math.sin(angle2)
            y8 = 0.30 * math.cos(angle2)

            self.quad(x5, y5, x6, y6, x7, y7, x8, y8)

            self.extrude(x6, y6, x7, y7)
            self.extrude(x8, y8, x5, y5)

        self.gl.glEnd()
        self.gl.glEndList()

        return genList

    def quad(self, x1, y1, x2, y2, x3, y3, x4, y4):
        self.setColor(self.trolltechGreen)

        self.gl.glVertex3d(x1, y1, -0.05)
        self.gl.glVertex3d(x2, y2, -0.05)
        self.gl.glVertex3d(x3, y3, -0.05)
        self.gl.glVertex3d(x4, y4, -0.05)

        self.gl.glVertex3d(x4, y4, +0.05)
        self.gl.glVertex3d(x3, y3, +0.05)
        self.gl.glVertex3d(x2, y2, +0.05)
        self.gl.glVertex3d(x1, y1, +0.05)

    def extrude(self, x1, y1, x2, y2):
        self.setColor(self.trolltechGreen.darker(250 + int(100 * x1)))

        self.gl.glVertex3d(x1, y1, +0.05)
        self.gl.glVertex3d(x2, y2, +0.05)
        self.gl.glVertex3d(x2, y2, -0.05)
        self.gl.glVertex3d(x1, y1, -0.05)

    def normalizeAngle(self, angle):
        while angle < 0:
            angle += 360 * 16
        while angle > 360 * 16:
            angle -= 360 * 16
        return angle

    def setClearColor(self, c):
        self.gl.glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF())

    def setColor(self, c):
        self.gl.glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF())
	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()
Пример #31
0
class ObjectRotationManager:
    """
        Allows a basic rotation system in the subclass QGLWidget
        
        In the subclass is mandatory to add as class parameters:
        
        xRotationChanged=pyqtSignal(int)
        yRotationChanged=pyqtSignal(int)
        zRotationChanged=pyqtSignal(int)

    """
    def __init__(self):
        self.xRot = 0
        self.yRot = 0
        self.zRot = 0

        self.lastPos = QPoint()

    def normalizeAngle(self, angle):
        while angle < 0:
            angle += 360 * 16
        while angle > 360 * 16:
            angle -= 360 * 16
        return angle

    def xRotation(self):
        return self.xRot

    def yRotation(self):
        return self.yRot

    def zRotation(self):
        return self.zRot

    def mousePressEvent(self, event):
        self.lastPos = QPoint(event.pos())

    def mouseMoveEvent(self, event):
        dx = event.x() - self.lastPos.x()
        dy = event.y() - self.lastPos.y()

        if event.buttons() & Qt.LeftButton:
            self.setXRotation(self.xRot + 8 * dy)
            self.setYRotation(self.yRot + 8 * dx)
        elif event.buttons() & Qt.RightButton:
            self.setXRotation(self.xRot + 8 * dy)
            self.setZRotation(self.zRot + 8 * dx)

        self.lastPos = QPoint(event.pos())

    def setXRotation(self, angle):
        angle = self.normalizeAngle(angle)
        if angle != self.xRot:
            self.xRot = angle
            self.xRotationChanged.emit(angle)
            self.updateGL()

    def setYRotation(self, angle):
        angle = self.normalizeAngle(angle)
        if angle != self.yRot:
            self.yRot = angle
            self.yRotationChanged.emit(angle)
            self.updateGL()

    def setZRotation(self, angle):
        angle = self.normalizeAngle(angle)
        if angle != self.zRot:
            self.zRot = angle
            self.zRotationChanged.emit(angle)
            self.updateGL()
Пример #32
0
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]))
Пример #33
0
class RenderArea(QWidget):
	  
	Line, Points, Polyline, Polygon, Rect, RoundedRect, Ellipse, Arc, Chord, \
			Pie, Path, Text, Pixmap = range(13)
  
	def __init__(self, machine, parent=None):
		super(RenderArea, self).__init__(parent)
  
		self.pen = QPen()
		self.brush = QBrush()
		
		self.antialiased = True
  
		self.setBackgroundRole(QPalette.Base)
		self.setAutoFillBackground(True)
		
		self.machine = machine

		self.dist_radius = min(self.width() / 4, self.height() / 4) * 1.5
		self.dist_center = QPoint(self.width() / 2.0, self.height() / 2.0)
		self.n_states = len(self.machine.getStates())

		self.state_radius = self.funcc(self.dist_radius, self.n_states)
		self.active = -1
		self.t_active = -1

		self.pts = []


		#Brushes
		linearGradient = QLinearGradient(-self.state_radius, -self.state_radius, self.state_radius, self.state_radius)
		linearGradient.setColorAt(0.0, Qt.darkGreen)
		linearGradient.setColorAt(0.7, Qt.green)
		linearGradient.setColorAt(0.3, Qt.green)
		linearGradient.setColorAt(1.0, Qt.white)
		self.greenGradientBrush = QBrush(linearGradient)

		linearGradient = QLinearGradient(-self.state_radius, -self.state_radius, self.state_radius, self.state_radius)
		linearGradient.setColorAt(0.0, Qt.darkGray)
		linearGradient.setColorAt(0.7, Qt.lightGray)
		linearGradient.setColorAt(0.3, Qt.gray)
		linearGradient.setColorAt(1.0, Qt.white)
		self.grayGradientBrush = QBrush(linearGradient)
		self.setBrush(self.grayGradientBrush)
		#end brushes

	def funcc(self, r, n):
		return int((r*0.05) / (n*0.04))

	def minimumSizeHint(self):
		return QSize(100, 100)
  
	def sizeHint(self):
		return QSize(400, 200)
  
	def setPen(self, pen):
		self.pen = pen
		self.update()
  
	def setBrush(self, brush):
		self.brush = brush
		self.update()
 
	def resizeEvent(self, event):
		self.dist_center = QPoint(self.width() / 2.0, self.height() / 2.0)
		self.dist_radius = min(self.width() / 4, self.height() / 4) * 1.5
		self.state_radius = self.funcc(self.dist_radius, self.n_states)
		self.update()

	def poly(self, pts):
		return QPolygonF(map(lambda p: QPointF(*p), pts))

	def wave(self):
		
		t = self.machine.getActiveTransition()
		if t != None:

			init = QPoint(t.getOrig()[0], t.getOrig()[1])
			end = QPoint(t.getDest()[0], t.getDest()[1])
			angle = t.getAngle()
			#print('processing transition', t.id, t.orig, t.dest)
			while t.isActive():
			#for i in range(3):	#for testing
				self.pts = [[init.x(), init.y()], [end.x(), end.y()]]
				if self.pts[0][0] <= self.pts[1][0] and self.pts[0][1] >= self.pts[1][1]:
					while self.pts[0][0] <= self.pts[1][0] and self.pts[0][1] >= self.pts[1][1]:
						self.sumPoint(angle)
				elif self.pts[0][0] <= self.pts[1][0] and self.pts[0][1] <= self.pts[1][1]:
					while self.pts[0][0] <= self.pts[1][0] and self.pts[0][1] <= self.pts[1][1]:
						self.sumPoint(angle)
				elif self.pts[0][0] >= self.pts[1][0] and self.pts[0][1] >= self.pts[1][1]:
					while self.pts[0][0] >= self.pts[1][0] and self.pts[0][1] >= self.pts[1][1]:
						self.sumPoint(angle)
				elif self.pts[0][0] >= self.pts[1][0] and self.pts[0][1] <= self.pts[1][1]:
					while self.pts[0][0] >= self.pts[1][0] and self.pts[0][1] <= self.pts[1][1]:
						self.sumPoint(angle)
						

	def sumPoint(self, angle):
		self.pts[0][0] += (self.state_radius * math.cos(angle) * 0.1)
		self.pts[0][1] -= (self.state_radius * math.sin(angle) * 0.1)
		self.update()
		QApplication.processEvents()
		time.sleep(0.025)

	def paintEvent(self, event):
		  
		painter = QPainter(self)
		painter.setPen(self.pen)
		painter.setBrush(self.brush)
		if self.antialiased:
			painter.setRenderHint(QPainter.Antialiasing)

		angle_step = 360 / self.n_states

		painter.save()	#Save_1. Save the state of the system (push matrix)
		painter.translate(self.dist_center.x(), self.dist_center.y())		# go to the center of the render area
		painter.rotate(-180)	#to start painting from the left side of the circle (clockwise)

		#center of the circumference where through we are going to paint our states 
		x = self.dist_radius * math.cos(0)	
		y = self.dist_radius * math.sin(0)


		for h in range(self.n_states):

			rot = angle_step * h 	# each state is equidistant from the others. We paint them in circles

			painter.save()			#Save_2
			painter.rotate(rot)		#now our system is pointing to the next state to be drawn
			painter.translate(x,y)	#now our origin is in the center of the next state to be drawn

			#if the state is active, fill it green
			if self.machine.getState(h).isActive():	
				painter.setBrush(self.greenGradientBrush)			
			painter.drawEllipse(QPoint(0,0), self.state_radius, self.state_radius)	#draw the new state

			#global position of transformed coordinates (before any transformation, origin at top-left corner)
			gx = painter.worldTransform().map(QPoint(0,0)).x()
			gy = painter.worldTransform().map(QPoint(0,0)).y()
			self.machine.getState(h).setPos(gx, gy)		#store the center of the state without any transformation applied

			# text transformation. Our origin is still in the center of the current state
			painter.save()			#Save_3
			painter.rotate(180)		#making the text go vertical
			painter.rotate(-rot)	#undoing the rotation made for painting the state. No the text is horizontal
			font = painter.font();
			font.setPixelSize(self.state_radius*.4);
			painter.setFont(font);
			rect = QRect(-self.state_radius, -self.state_radius, self.state_radius*2, self.state_radius*2)
			painter.drawText(rect, Qt.AlignCenter, self.machine.getState(h).getName());
			painter.restore()	#Restore_3
			#end text transformation

			painter.restore()	#Restore_2
			
		painter.restore()	#Restore_1. Restore the state of the system (pop matrix)

		
		#drawing transitions. Line between states
		painter.save()	# Save_4
		pptv = QTransform()		#Define a new transformation. Needed to rotate the system along other axis than Z
		pptv.translate(0, self.height())	#We are now at the bottom-left corner of the screen
		pptv.rotate(-180, Qt.XAxis)			#Rotate along the X-axis so now we are in a typical cartesian system.
		painter.setTransform(pptv)			#Apply the transformation
		states = self.machine.getStates()
		for state in states:
			transitions = state.getTransitions()
			for transition in transitions:
				#get the center of the origin and destination states in our current system state
				orig = QPoint(state.getPos()[0], state.getPos()[1])
				end = QPoint(self.machine.getState(transition.getStateEnd()).getPos()[0], self.machine.getState(transition.getStateEnd()).getPos()[1])
				# get those coordinates without transformation
				orig2 = QPoint(painter.worldTransform().map(orig))
				end2 = QPoint(painter.worldTransform().map(end))

				#get the angle between states centers and the horizon
				angle = math.atan2(end2.y() - orig2.y(), end2.x() - orig2.x())

				#get the coordinates of the starting point of the transition (it starts in the bound of the state, not in the center)
				newX = self.state_radius * math.cos(angle) + orig2.x()
				newY = self.state_radius * math.sin(angle) + orig2.y()
				#now the transition starts at the border, not in the center
				orig2.setX(newX)
				orig2.setY(newY)

				#same for the destination state
				angle2 = math.atan2(orig2.y() - end2.y(), orig2.x() - end2.x())
				newX2 = self.state_radius * math.cos(angle2) + end2.x()
				newY2 = self.state_radius * math.sin(angle2) + end2.y()
				end2.setX(newX2)
				end2.setY(newY2)

				#draw the line between the origin and destination states
				painter.drawLine(orig2, end2)
				#get the start and the end of the transition untransformed
				init = QPoint(painter.worldTransform().map(orig2))
				end = QPoint(painter.worldTransform().map(end2))
				#store that info
				transition.setOrig(init.x(), init.y())
				transition.setDest(end.x(), end.y())	
				transition.setAngle(angle)
		painter.restore() #Restore_4


		#Appliying style to the transitions
		painter.setPen(QPen(QColor(Qt.gray), 3))
		for state in self.machine.getStates():
			for transition in state.getTransitions():
				#get the start and end coordinates of the transition
				i = QPoint(transition.getOrig()[0], transition.getOrig()[1])
				o = QPoint(transition.getDest()[0], transition.getDest()[1])			
				painter.drawPolyline(i, o)

				#Drawing the arrow at the end of the transition
				painter.save()	#Save_5
				painter.setPen(QPen(QColor(Qt.gray), 2))
				painter.translate(transition.getDest()[0],transition.getDest()[1])	#Go to the end of the transition
				painter.rotate(90 - transition.getAngle()*180/math.pi)		#Rotate to point in the direction of the transition

				#coordinates of the arrow (triangle)
				a = QPoint(0,0)
				b = QPoint(-5,10)
				c = QPoint(5,10)

				#coordinates of the arrow untransformed
				a1 = painter.worldTransform().map(a)
				b1 = painter.worldTransform().map(b)
				c1 = painter.worldTransform().map(c)

				#Drawin the actual arrow
				pointer = QPolygon([a,b,c])
				painter.drawPolygon(pointer)
				painter.restore()	#Restore_5

				#For the animation of the transition
				painter.save()	#Save_6
				if transition.isActive():	#if the current transition is the active one the wave function will be running, so it's updating the canvas

					painter.setPen(QPen(QColor(Qt.green), 3))
					painter.drawPolyline(i,o)
					
					painter.setPen(QPen(QColor(Qt.gray), 3))
					painter.drawPolyline(self.poly(self.pts))

					#Draw the arrow in the active state (red arrow)
					painter.setBrush(QBrush(QColor(255, 0, 0)))
					painter.setPen(QPen(QColor(Qt.red), 2))
					pointer = QPolygon([a1,b1,c1])
					painter.drawPolygon(pointer)
					
					#Ball that follows the line animation
					for x, y in self.pts:
						painter.drawEllipse(QRectF(self.pts[0][0] - 4, self.pts[0][1] - 4, 8, 8))
				painter.restore()	#Restore_6

				#Painting the text of the transition
				painter.save()	#Save_7
				pptv = QTransform()
				painter.setPen(QPen(QColor(Qt.black), 3))
				#get the middle point of the transition
				middleX = (transition.getOrig()[0] + transition.getDest()[0]) /2	
				middleY = (transition.getOrig()[1] + transition.getDest()[1]) /2
				pptv.translate(middleX, middleY)	#translate to that point
				painter.setTransform(pptv)			#apply the transformation
				font = painter.font();
				font.setPixelSize(self.state_radius*.2);
				painter.setFont(font);
				rect = QRect(-self.state_radius, -self.state_radius, self.state_radius*2, self.state_radius*2)
				name = str(transition.getId())+ '. ' + transition.getName()
				painter.drawText(rect, Qt.AlignCenter, name)
				painter.restore()	#Restore_7


  
		#paint the actual canvas
		painter.setPen(self.palette().dark().color())
		painter.setBrush(Qt.NoBrush)
		painter.drawRect(QRect(0, 0, self.width() - 1, self.height() - 1))


	def start(self,n):
		'''print('active', n)
		self.active = n%3
		self.deactivateAll()
		self.machine.setStateActive(self.active, True)
		#time.sleep(5)
		self.t_active = n%3
		self.wave()

		for i in range(self.n_states):
			print('active', i)
			self.active = i
			self.deactivateAll()
			self.machine.setStateActive(self.active, True)
			self.update()
			QApplication.processEvents()
			time.sleep(2)

			self.t_active = i
			self.deactivateAll()
			self.machine.setTransitionActive  (self.t_active, True)
			for i in self.machine.getTransitions():
				print (i.isActive())
			self.update()
			QApplication.processEvents()
			self.wave()'''

	def stop(self):
		self.machine.deactivateAll()
Пример #34
0
    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]
Пример #35
0
 def mouseMoveEvent(self, event):
     delta = QPoint(event.globalPos() - self.oldPos)
     print(delta.x(), delta.y())
     self.MainWindow.move(self.MainWindow.x() + delta.x(),
                          self.MainWindow.y() + delta.y())
     self.oldPos = event.globalPos()
Пример #36
0
 def mouseMoveEvent(self, e):
     delta = QPoint(e.globalPos() - self.oldPos)
     self.move(self.x() + delta.x(), self.y() + delta.y())
     self.oldPos = e.globalPos()
Пример #37
0
class PictureBox(QLabel):
    changedNumberRegions = pyqtSignal(int)

    def __init__(self, image, regions, parent=None):

        QLabel.__init__(self, parent)
        self.rubberBand = QRubberBand(QRubberBand.Rectangle, self)
        self.origin = QPoint()
        self.regions = None
        self.image = image

        def region_to_rect(region):
            y1, x1, y2, x2 = region.bbox
            return QRect(x1, y1, x2 - x1, y2 - y1)

        self.regions = list(map(region_to_rect, regions))
        self._update_picture()

    def mousePressEvent(self, event):
        pal = QPalette()
        if event.button() == Qt.LeftButton:
            pal.setBrush(QPalette.Highlight, QBrush(Qt.blue))
        elif event.button() == Qt.RightButton:
            pal.setBrush(QPalette.Highlight, QBrush(Qt.green))
        self.rubberBand.setPalette(pal)
        self.origin = QPoint(event.pos())
        self.rubberBand.setGeometry(QRect(self.origin, QSize()))
        self.rubberBand.show()

    def mouseMoveEvent(self, event):
        if not self.origin.isNull():
            self.rubberBand.setGeometry(
                QRect(self.origin, event.pos()).normalized())

    def mouseReleaseEvent(self, event):
        if event.button() == Qt.LeftButton:
            drawnRect = QRect(self.origin, event.pos()).normalized()
            for region in self.getIntersectedRegions(drawnRect):
                self.regions.remove(region)
        elif event.button() == Qt.RightButton:
            drawnRect = QRect(self.origin, event.pos()).normalized()
            meanArea = np.mean([r.width() * r.height() for r in self.regions])
            meanHeight = np.mean([r.height() for r in self.regions])
            meanWidth = np.mean([r.width() for r in self.regions])
            if drawnRect.width() * drawnRect.height() * 2 < meanArea:
                rect = QRect(self.origin.x() - meanWidth / 2,
                             self.origin.y() - meanHeight / 2, meanWidth,
                             meanHeight)
                self.regions.append(rect)
            else:
                self.regions.append(drawnRect)
        self.rubberBand.hide()
        self._update_picture()

    def getIntersectedRegions(self, drawnRect):
        result = []
        for region in self.regions:
            if region.intersects(drawnRect):
                result.append(region)
        return result

    def _update_regions(self):
        pixmap = self._get_pixmap()
        paint = QPainter(pixmap)
        paint.setPen(QColor("green"))
        for region in self.regions:
            paint.drawRect(region)
            # rect = mpatches.Rectangle((minc, minr), maxc - minc, maxr - minr,
            #                          fill=False, edgecolor='green', linewidth=2)
        del paint
        return pixmap

    def savePicture(self, fname):
        pixmap = self._update_regions()
        return pixmap.save(fname)

    def _update_picture(self):
        pixmap = self._update_regions()
        self.setAlignment(Qt.AlignLeft | Qt.AlignTop)
        self.setPixmap(pixmap)
        self.changedNumberRegions.emit(len(self.regions))

    def _get_pixmap(self):
        # Convert image to QImage
        qimg = qimage2ndarray.array2qimage(self.image, True)
        return QPixmap(qimg)
Пример #38
0
class GLWidget(QOpenGLWidget):

    clicked = pyqtSignal()

    PROGRAM_VERTEX_ATTRIBUTE, PROGRAM_TEXCOORD_ATTRIBUTE = range(2)

    vsrc = """
attribute highp vec4 vertex;
attribute mediump vec4 texCoord;
varying mediump vec4 texc;
uniform mediump mat4 matrix;
void main(void)
{
    gl_Position = matrix * vertex;
    texc = texCoord;
}
"""

    fsrc = """
uniform sampler2D texture;
varying mediump vec4 texc;
void main(void)
{
    gl_FragColor = texture2D(texture, texc.st);
}
"""

    coords = (((+1, -1, -1), (-1, -1, -1), (-1, +1, -1), (+1, +1, -1)),
              ((+1, +1, -1), (-1, +1, -1), (-1, +1, +1), (+1, +1, +1)),
              ((+1, -1, +1), (+1, -1, -1), (+1, +1, -1), (+1, +1, +1)),
              ((-1, -1, -1), (-1, -1, +1), (-1, +1, +1),
               (-1, +1, -1)), ((+1, -1, +1), (-1, -1, +1), (-1, -1, -1),
                               (+1, -1, -1)), ((-1, -1, +1), (+1, -1, +1),
                                               (+1, +1, +1), (-1, +1, +1)))

    def __init__(self, parent=None):
        super(GLWidget, self).__init__(parent)

        self.clearColor = QColor(Qt.black)
        self.xRot = 0
        self.yRot = 0
        self.zRot = 0
        self.program = None

        self.lastPos = QPoint()

    def minimumSizeHint(self):
        return QSize(50, 50)

    def sizeHint(self):
        return QSize(200, 200)

    def rotateBy(self, xAngle, yAngle, zAngle):
        self.xRot += xAngle
        self.yRot += yAngle
        self.zRot += zAngle
        self.update()

    def setClearColor(self, color):
        self.clearColor = color
        self.update()

    def initializeGL(self):
        self.gl = self.context().versionFunctions()
        self.gl.initializeOpenGLFunctions()

        self.makeObject()

        self.gl.glEnable(self.gl.GL_DEPTH_TEST)
        self.gl.glEnable(self.gl.GL_CULL_FACE)

        vshader = QOpenGLShader(QOpenGLShader.Vertex, self)
        vshader.compileSourceCode(self.vsrc)

        fshader = QOpenGLShader(QOpenGLShader.Fragment, self)
        fshader.compileSourceCode(self.fsrc)

        self.program = QOpenGLShaderProgram()
        self.program.addShader(vshader)
        self.program.addShader(fshader)
        self.program.bindAttributeLocation('vertex',
                                           self.PROGRAM_VERTEX_ATTRIBUTE)
        self.program.bindAttributeLocation('texCoord',
                                           self.PROGRAM_TEXCOORD_ATTRIBUTE)
        self.program.link()

        self.program.bind()
        self.program.setUniformValue('texture', 0)

        self.program.enableAttributeArray(self.PROGRAM_VERTEX_ATTRIBUTE)
        self.program.enableAttributeArray(self.PROGRAM_TEXCOORD_ATTRIBUTE)
        self.program.setAttributeArray(self.PROGRAM_VERTEX_ATTRIBUTE,
                                       self.vertices)
        self.program.setAttributeArray(self.PROGRAM_TEXCOORD_ATTRIBUTE,
                                       self.texCoords)

    def paintGL(self):
        self.gl.glClearColor(self.clearColor.redF(), self.clearColor.greenF(),
                             self.clearColor.blueF(), self.clearColor.alphaF())
        self.gl.glClear(self.gl.GL_COLOR_BUFFER_BIT
                        | self.gl.GL_DEPTH_BUFFER_BIT)

        m = QMatrix4x4()
        m.ortho(-0.5, 0.5, 0.5, -0.5, 4.0, 15.0)
        m.translate(0.0, 0.0, -10.0)
        m.rotate(self.xRot / 16.0, 1.0, 0.0, 0.0)
        m.rotate(self.yRot / 16.0, 0.0, 1.0, 0.0)
        m.rotate(self.zRot / 16.0, 0.0, 0.0, 1.0)

        self.program.setUniformValue('matrix', m)

        for i, texture in enumerate(self.textures):
            texture.bind()
            self.gl.glDrawArrays(self.gl.GL_TRIANGLE_FAN, i * 4, 4)

    def resizeGL(self, width, height):
        side = min(width, height)
        self.gl.glViewport((width - side) // 2, (height - side) // 2, side,
                           side)

    def mousePressEvent(self, event):
        self.lastPos = event.pos()

    def mouseMoveEvent(self, event):
        dx = event.x() - self.lastPos.x()
        dy = event.y() - self.lastPos.y()

        if event.buttons() & Qt.LeftButton:
            self.rotateBy(8 * dy, 8 * dx, 0)
        elif event.buttons() & Qt.RightButton:
            self.rotateBy(8 * dy, 0, 8 * dx)

        self.lastPos = event.pos()

    def mouseReleaseEvent(self, event):
        self.clicked.emit()

    def makeObject(self):
        self.textures = []
        self.texCoords = []
        self.vertices = []

        root = QFileInfo(__file__).absolutePath()

        for i in range(6):
            self.textures.append(
                QOpenGLTexture(
                    QImage(root + ('/images/side%d.png' %
                                   (i + 1))).mirrored()))

            for j in range(4):
                self.texCoords.append(((j == 0 or j == 3), (j == 0 or j == 1)))

                x, y, z = self.coords[i][j]
                self.vertices.append((0.2 * x, 0.2 * y, 0.2 * z))
Пример #39
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()
Пример #40
0
class Ui_MeasureWindow(QtWidgets.QWidget):
    def __init__(self, parent):
        super().__init__()
        self.main = parent
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding,
                                           QtWidgets.QSizePolicy.Maximum)
        self.setSizePolicy(sizePolicy)
        self.setWindowTitle("Channel Measurement")
        self.setWindowIcon(QtGui.QIcon('res\\m_icon.ico'))
        #self.setWindowFlags(QtCore.Qt.WindowFlags(QtCore.Qt.FramelessWindowHint))
        self.layout1 = QtWidgets.QHBoxLayout()
        self.tableWidget = QtWidgets.QTableWidget(self)
        self.tableWidget.setSizeAdjustPolicy(
            QtWidgets.QAbstractScrollArea.AdjustToContents)
        self.tableWidget.setAlternatingRowColors(True)
        self.tableWidget.setSizePolicy(sizePolicy)
        self.tableWidget.setColumnCount(12)
        self.tableWidget.setRowCount(0)
        self.tableWidget.setLineWidth(5)
        self.layout1.addWidget(self.tableWidget)
        self.layout1.setContentsMargins(0, 0, 0, 0)
        self.layout1.setSizeConstraint(QtWidgets.QLayout.SetMaximumSize)
        self.tableWidget.verticalHeader().setVisible(False)
        header_list = [
            "Channel", "Vmin", "Vmax", "Vmean", "Vrms", "Vpk-pk", "Freq",
            "T Period", "PWidth+", "PWidth-", "Duty+", "Duty-"
        ]
        font = QtGui.QFont("Arial", 9)
        font.setBold(True)
        header_num = 0
        for headers in header_list:
            header_item = QtWidgets.QTableWidgetItem(headers)
            header_item.setFont(font)
            self.tableWidget.setHorizontalHeaderItem(header_num, header_item)
            header_num += 1

        self.tableWidget.resizeColumnsToContents()
        self.first_run = True
        #self.title_bar = custom_TitleBar(self)
        #self.layout.addWidget(self.title_bar)
        #flags=QtCore.Qt.WindowFlags(QtCore.Qt.FramelessWindowHint)# | QtCore.Qt.WindowStaysOnTopHint)
        #self.setWindowFlags(QtCore.Qt.WindowFlags(QtCore.Qt.FramelessWindowHint))
        #self.title_bar.pressing = False
        self.freq_Pulse_Duty_list = []
        self.Ch_Vmins = []
        self.Ch_Vmaxs = []
        self.Ch_Vmeans = []
        self.Ch_Vrms = []
        self.Ch_pk2pk = []

        self.freq_Pulse_Duty_list_act = []
        self.Ch_Vmins_act = []
        self.Ch_Vmaxs_act = []
        self.Ch_Vrms_act = []
        self.Ch_pk2pk_act = []

        self.closed = False
        self.shown = False
        self.was_shown = False
        self.resize_by_func = False
        self.round_factor_is_set = True
        self.round_factor = 3
        self.opacity_ = 160
        self.initial_members_count = 0
        self.Each_Row_height_saved = 0
        self.Actual_win_height_0_row_saved = 0
        self.table_height_offset_saved = 0
        self.tableWidget_mWin_size_same = False
        self.win_pos = QPoint(0, 0)
        self.get_config()

    def update_(self):
        self.calc_Vmean()
        self.calc_Vrms()
        self.calc_pk2pk()
        self.Calc_Times()

        measurement_list = []
        measurement_list_actual = []
        ch_name_list = []
        mem = 0
        for members in self.main.ch_name_col_list:
            ch_name_list.append(self.main.ch_name_col_list[mem][0])
            mem += 1
        Ch_Vmeans = self.set_Units(self.Ch_Vmeans, 0)
        measurement_list = [
            ch_name_list, self.Ch_Vmins, self.Ch_Vmaxs, Ch_Vmeans,
            self.Ch_Vrms, self.Ch_pk2pk, self.freq_Pulse_Duty_list
        ]

        measurement_list_actual = [
            ch_name_list, self.Ch_Vmins_act, self.Ch_Vmaxs_act, self.Ch_Vmeans,
            self.Ch_Vrms_act, self.Ch_pk2pk_act, self.freq_Pulse_Duty_list_act
        ]
        ##print(measurement_list)

        row_num = 0
        ###CH_name Vmin, Vmax, Vmean Vrms PktoPk Freq TPeriod Pwidth+ PWidth- Duty+ Duty -
        for members in self.main.ch_name_col_list:
            self.tableWidget.insertRow(row_num)

            for i in range(self.tableWidget.columnCount()):
                if i <= 5:
                    ##print("Items:",row_num,i,measurement_list[i][row_num])
                    self.tableWidget.setItem(
                        row_num, i,
                        QtWidgets.QTableWidgetItem(
                            measurement_list[i][row_num]))
                    if i != 0:
                        self.tableWidget.item(row_num, i).setToolTip(
                            str(measurement_list_actual[i][row_num]) + "mv")
                    else:
                        self.tableWidget.item(row_num, i).setToolTip(
                            str(measurement_list_actual[i][row_num]))

                    self.tableWidget.item(row_num,
                                          i).setTextAlignment(Qt.AlignCenter)
                    col = QtGui.QColor(members[1])
                    col.setAlpha(self.opacity_)
                    self.tableWidget.item(row_num,
                                          i).setBackground(QtGui.QColor(col))
                else:
                    j = i - 6
                    self.tableWidget.setItem(
                        row_num, i,
                        QtWidgets.QTableWidgetItem(
                            measurement_list[6][row_num][j]))
                    if j == 0:
                        self.tableWidget.item(row_num, i).setToolTip(
                            str(measurement_list_actual[6][row_num][j]) + "Hz")
                    elif j > 0 and j < 4:
                        self.tableWidget.item(row_num, i).setToolTip(
                            str(measurement_list_actual[6][row_num][j]) + "s")
                    else:
                        self.tableWidget.item(row_num, i).setToolTip(
                            str(measurement_list_actual[6][row_num][j]) + "%")

                    col = QtGui.QColor(members[1])
                    col.setAlpha(self.opacity_)
                    self.tableWidget.item(row_num,
                                          i).setBackground(QtGui.QColor(col))
                    self.tableWidget.item(row_num,
                                          i).setTextAlignment(Qt.AlignCenter)
                #print(row_num,"  ",i)
            row_num += 1
        self.initial_members_count = row_num
        self.tableWidget.resizeColumnsToContents()
        self.tableWidget.resizeRowsToContents()
        self.first_run = False

    def Update_UI(self):
        if self.initial_members_count != len(
                self.main.ch_name_col_list) or self.main.file_edited == True:
            if self.shown == True:
                Each_Row_height, Actual_win_height_0_row, table_height_offset = self.read_dimentions(
                )
            elif self.was_shown:
                Each_Row_height = self.Each_Row_height_saved
                Actual_win_height_0_row = self.Actual_win_height_0_row_saved
                table_height_offset = self.table_height_offset_saved

            for i in range(self.tableWidget.rowCount()):
                self.tableWidget.removeRow(0)
            self.first_run = True

            self.update_()

            if self.shown == True or self.was_shown == True:
                TH = int((self.tableWidget.rowCount() * Each_Row_height) +
                         Actual_win_height_0_row)
                #print("TH=",TH)
                self.resize_by_func = True
                self.tableWidget.resize(self.tableWidget.size().width(),
                                        TH + table_height_offset)
                self.resize(self.size().width(), TH)
                #print("MeasureWin Size Updated")
        self.activateWindow()

    def read_dimentions(self):
        mWin_Height = self.size().height()
        table_height = self.tableWidget.height()
        table_height_offset = table_height - mWin_Height
        T_row_Height = 0
        row_count = self.tableWidget.rowCount()
        for i in range(row_count):
            T_row_Height += self.tableWidget.rowHeight(i)
        Each_Row_height = T_row_Height / row_count
        Actual_win_height_0_row = mWin_Height - T_row_Height
        ##print("AWH=",Actual_win_height_0_row," Prow_count=",row_count,"PT_row_Height=",T_row_Height,"mWin_Height=",mWin_Height,"table_height=",table_height)
        return Each_Row_height, Actual_win_height_0_row, table_height_offset

############################################################ MATH ###########################################################################

    def calc_Vmean(self):
        ch_num = 0
        for members in self.main.ch_name_col_list:
            self.Ch_Vmeans.append(np.mean(self.main.y[ch_num]))
            ch_num += 1

    def calc_Vrms(self):
        ch_num = 0
        Ch_Vrms = []
        vrms = []
        vsq = []
        for members in self.main.ch_name_col_list:
            vsq = np.square(self.main.y[ch_num])
            Ch_Vrms.append(np.sqrt(np.mean(vsq)))
            ch_num += 1
        self.Ch_Vrms_act = Ch_Vrms
        self.Ch_Vrms = self.set_Units(Ch_Vrms, 0)

    def calc_pk2pk(self):
        ch_num = 0
        Ch_pk2pk = []
        Ch_Vmins = []
        Ch_Vmaxs = []
        for members in self.main.ch_name_col_list:
            vmax = max(self.main.y[ch_num])
            vmin = min(self.main.y[ch_num])
            Ch_pk2pk.append(vmax - vmin)
            ##print(vmax-vmin)
            Ch_Vmins.append(vmin)
            Ch_Vmaxs.append(vmax)
            ch_num += 1
        self.Ch_pk2pk = self.set_Units(Ch_pk2pk, 0)
        self.Ch_pk2pk_act = Ch_pk2pk
        self.Ch_Vmaxs = self.set_Units(Ch_Vmaxs, 0)
        self.Ch_Vmaxs_act = Ch_Vmaxs
        self.Ch_Vmins = self.set_Units(Ch_Vmins, 0)
        self.Ch_Vmins_act = Ch_Vmins

    def Calc_Times(self):
        self.freq_Pulse_Duty_list_act = []
        self.freq_Pulse_Duty_list = []
        #self.calc_Vmean()
        y_mean = self.Ch_Vmeans
        ch_num = 0
        self.freq_Pulse_Duty_list = []
        for members in self.main.ch_name_col_list:
            #print("CH NAME:",self.main.ch_name_col_list[ch_num][0]," CH Vmean:",y_mean[ch_num])
            FPD = self.single_Ch_freq(
                ch_num, y_mean[ch_num]
            )  #freq,period,mean_pos_pulse,mean_neg_pulse,Duty_P,Duty_N
            self.freq_Pulse_Duty_list_act.append(FPD)
            FPD = self.set_Units(FPD, 1)
            self.freq_Pulse_Duty_list.append(FPD)
            ch_num += 1

    def single_Ch_freq(self, ch_number, ch_V_mean):
        t_list = []
        dt_list = []
        pulse_bool_list = []
        count_dir_bool = 0
        for i in range(len(self.main.y[ch_number]) - 1):
            if self.main.y[ch_number][i + 1] > self.main.y[ch_number][
                    i] and self.main.y[ch_number][i + 1] > ch_V_mean:
                if count_dir_bool == -1:
                    t_list.append(self.main.x[ch_number][i + 1])
                    pulse_bool_list.append(1)
                    #print("line:",str(i+1),"X:",str(self.main.x[ch_number][i+1]),"Y:",str(self.main.y[ch_number][i+1]),"1")
                count_dir_bool = 1
            elif self.main.y[ch_number][i + 1] < self.main.y[ch_number][
                    i] and self.main.y[ch_number][i + 1] < ch_V_mean:
                if count_dir_bool == 1:
                    t_list.append(self.main.x[ch_number][i + 1])
                    pulse_bool_list.append(-1)
                    #print("line:",str(i+1),"X:",str(self.main.x[ch_number][i+1]),"Y:",str(self.main.y[ch_number][i+1]),"-1")
                count_dir_bool = -1
        for j in range((len(t_list) - 1)):
            dt = t_list[j + 1] - t_list[j]
            ##print("",",",t_list[j],",",",",pulse_bool_list[j],file=self.main.file_)
            ##print(dt,file=self.main.file_)
            ##print("",",",t_list[j+1],",",",",pulse_bool_list[j+1],file=self.main.file_)
            puse_bool = pulse_bool_list[j + 1] - pulse_bool_list[j]
            ##print(dt,",",t_list[j+1],",",t_list[j],",",puse_bool,file=self.main.file_)
            dt_list.append([dt, puse_bool])
        #print(dt_list)
        #dt_list=sorted(dt_list,key=itemgetter(0),reverse=True)
        max_end_indx_pos = -1
        max_end_indx_neg = -1
        mean_pos_pulse = 0
        mean_neg_pulse = 0
        pos_pulse = []
        neg_pulse = []
        if len(dt_list) > 1:
            for i in range(len(dt_list)):
                if dt_list[i][1] == -2:
                    pos_pulse.append(dt_list[i][0])
                if dt_list[i][1] == 2:
                    neg_pulse.append(dt_list[i][0])
            pos_pulse = sorted(pos_pulse, reverse=True)
            neg_pulse = sorted(neg_pulse, reverse=True)
            for i in range(len(pos_pulse) - 1):
                rel_dev = (pos_pulse[i] - pos_pulse[i + 1]) / pos_pulse[i]
                #print("indx=",i," dtf=",dt_list[i+1]," dti=",dt_list[i]," rel_dev=",rel_dev)
                if rel_dev > 0.50:  #deviations above 50% of the max pulse width is neglected... (Considering stray)
                    max_end_indx_pos = i + 1
                    break
            for i in range(len(neg_pulse) - 1):
                rel_dev = (neg_pulse[i] - neg_pulse[i + 1]) / neg_pulse[i]
                #print("indx=",i," dtf=",dt_list[i+1]," dti=",dt_list[i]," rel_dev=",rel_dev)
                if rel_dev > 0.50:  #deviations above 50% of the max pulse width is neglected... (Considering stray)
                    max_end_indx_neg = i + 1
                    break
            if max_end_indx_pos >= 0:
                pos_pulse = pos_pulse[:max_end_indx_pos]
            if max_end_indx_neg >= 0:
                neg_pulse = neg_pulse[:max_end_indx_neg]

            mean_pos_pulse = np.mean(pos_pulse)
            mean_neg_pulse = np.mean(neg_pulse)
            mean_pulse = np.mean([mean_pos_pulse, mean_neg_pulse])
        elif len(dt_list) == 1:
            if dt_list[0][1] == 2:
                mean_neg_pulse = dt_list[0][0]
                mean_pulse = mean_neg_pulse

            if dt_list[0][1] == -2:
                mean_pos_pulse = dt_list[0][0]
                mean_pulse = mean_pos_pulse

        Duty_P = (mean_pos_pulse / (mean_pos_pulse + mean_neg_pulse)) * 100
        Duty_N = (mean_neg_pulse / (mean_pos_pulse + mean_neg_pulse)) * 100
        period = 2 * mean_pulse
        freq = (1 / (2 * mean_pulse))
        #print("Freq=",freq," +PWidth=",mean_pos_pulse," -PWidth=",mean_neg_pulse," Duty_P=",Duty_P," Duty_N",Duty_N)
        return freq, period, mean_pos_pulse, mean_neg_pulse, Duty_P, Duty_N

    def set_Units(self, data_list, measurable_flag):
        string_list = []
        round_b = self.round_factor_is_set
        round_f = self.round_factor
        if measurable_flag == 0:  ###volt
            for i in range(len(data_list)):

                if data_list[i] >= 1000:
                    if round_b:
                        string_list.append(
                            str(round(data_list[i] / 1000, round_f)) + " V")
                    else:
                        string_list.append(str(data_list[i] / 1000) + " V")
                else:
                    if round_b:
                        string_list.append(
                            str(round(data_list[i], round_f)) + " mV")
                    else:
                        string_list.append(str(data_list[i]) + " mV")

        elif measurable_flag == 1:  ###timmings
            for i in range(len(data_list)):
                if i == 0:
                    if data_list[i] >= 1000:
                        if round_b:
                            string_list.append(
                                str(round(data_list[i] / 1000, round_f)) +
                                " KHz")
                        else:
                            string_list.append(str(data_list[i]) + " KHz")
                    else:
                        if round_b:
                            string_list.append(
                                str(round(data_list[i], round_f)) + " Hz")
                        else:
                            string_list.append(str(data_list[i]) + " Hz")
                if i > 0 and i <= 3:
                    unit_ = ""
                    time_s = data_list[i] * 1e9
                    unit_ = "ns"
                    if time_s > 800:
                        time_s = time_s / 1000  ##in micros
                        unit_ = "us"
                        if time_s > 800:
                            time_s = time_s / 1000  ##in millis
                            unit_ = "ms"
                            if time_s > 800:
                                time_s = time_s / 1000  ##in Sec
                                unit_ = "s"
                    if round_b:
                        string_list.append(str(round(time_s, round_f)) + unit_)
                    else:
                        string_list.append(str(time_s) + unit_)
                elif i > 3:
                    if round_b:
                        string_list.append(
                            str(round(data_list[i], round_f)) + "%")
                    else:
                        string_list.append(str(data_list[i]) + "%")
        return string_list

#############################################################EVENTS#############################################################

    def closeEvent(self, event):
        self.closed = True
        self.shown = False
        self.was_shown = True

        QtWidgets.QWidget.closeEvent(self, event)

    def showEvent(self, event):

        QtWidgets.QWidget.showEvent(self, event)
        #print("shown")

        if isinstance(self.win_pos, str) == False:
            self.move(self.win_pos)
        if self.tableWidget_mWin_size_same == False:
            self.resize(
                self.tableWidget.size().width() - self.main.popup_width_offset,
                self.tableWidget.size().height() -
                self.main.popup_height_offset)
        else:
            self.resize(self.tableWidget.size().width(),
                        self.tableWidget.size().height())
        self.shown = True
        self.was_shown = False
        self.Each_Row_height_saved, self.Actual_win_height_0_row_saved, self.table_height_offset_saved = self.read_dimentions(
        )
        self.closed = False

    def resizeEvent(self, event):
        QtWidgets.QWidget.resizeEvent(self, event)
        if self.shown == True and self.resize_by_func == False:
            #print("resize")
            self.tableWidget.resize(self.size().width(), self.size().height())
            self.tableWidget_mWin_size_same = True
        self.resize_by_func = False

    def moveEvent(self, e):
        if self.closed == False:
            self.win_pos = self.pos()
        super(Ui_MeasureWindow, self).moveEvent(e)

    def get_pos(self):
        if isinstance(self.win_pos, str):
            return [0, 0]
        else:
            return self.win_pos.x(), self.win_pos.y()

    def set_pos(self, pos_):
        self.move(pos_[0], pos_[1])

    def get_config(self):
        if self.main.conf.Measurement_Window_Opacity != [None, False]:
            self.setWindowOpacity(self.main.conf.Measurement_Window_Opacity)
        if self.main.conf.Measurement_Window_always_on_top != [None, False]:

            if self.main.conf.Measurement_Window_always_on_top:
                self.setWindowFlags(
                    QtCore.Qt.WindowFlags(QtCore.Qt.WindowStaysOnTopHint))
            else:
                self.setWindowFlags(QtCore.Qt.WindowFlags())
Пример #41
0
def fillRegion(layer, fillOrigin):
    # Create that region that will hold the fill
    fillRegion = QRegion()
    # Silently quit if parameters are unsatisfactory
    if (not layer.contains(fillOrigin)):
        return fillRegion
    # Cache cell that we will match other cells against
    matchCell = layer.cellAt(fillOrigin)
    # Grab map dimensions for later use.
    layerWidth = layer.width()
    layerHeight = layer.height()
    layerSize = layerWidth * layerHeight
    # Create a queue to hold cells that need filling
    fillPositions = QList()
    fillPositions.append(fillOrigin)
    # Create an array that will store which cells have been processed
    # This is faster than checking if a given cell is in the region/list
    processedCellsVec = QVector()
    for i in range(layerSize):
        processedCellsVec.append(0xff)
    processedCells = processedCellsVec
    # Loop through queued positions and fill them, while at the same time
    # checking adjacent positions to see if they should be added
    while (not fillPositions.empty()):
        currentPoint = fillPositions.takeFirst()
        startOfLine = currentPoint.y() * layerWidth
        # Seek as far left as we can
        left = currentPoint.x()
        while (left > 0 and layer.cellAt(left - 1, currentPoint.y()) == matchCell):
            left -= 1
        # Seek as far right as we can
        right = currentPoint.x()
        while (right + 1 < layerWidth and layer.cellAt(right + 1, currentPoint.y()) == matchCell):
            right += 1
        # Add cells between left and right to the region
        fillRegion += QRegion(left, currentPoint.y(), right - left + 1, 1)
        # Add cell strip to processed cells
        for i in range(startOfLine + left, right + startOfLine, 1):
            processedCells[i] = 1
        # These variables cache whether the last cell was added to the queue
        # or not as an optimization, since adjacent cells on the x axis
        # do not need to be added to the queue.
        lastAboveCell = False
        lastBelowCell = False
        # Loop between left and right and check if cells above or
        # below need to be added to the queue
        for x in range(left, right+1):
            fillPoint = QPoint(x, currentPoint.y())
            # Check cell above
            if (fillPoint.y() > 0):
                aboveCell = QPoint(fillPoint.x(), fillPoint.y() - 1)
                if (not processedCells[aboveCell.y() * layerWidth + aboveCell.x()] and layer.cellAt(aboveCell) == matchCell):

                    # Do not add the above cell to the queue if its
                    # x-adjacent cell was added.
                    if (not lastAboveCell):
                        fillPositions.append(aboveCell)
                    lastAboveCell = True
                else:
                    lastAboveCell = False

                processedCells[aboveCell.y() * layerWidth + aboveCell.x()] = 1

            # Check cell below
            if (fillPoint.y() + 1 < layerHeight):
                belowCell = QPoint(fillPoint.x(), fillPoint.y() + 1)
                if (not processedCells[belowCell.y() * layerWidth + belowCell.x()] and layer.cellAt(belowCell) == matchCell):

                    # Do not add the below cell to the queue if its
                    # x-adjacent cell was added.
                    if (not lastBelowCell):
                        fillPositions.append(belowCell)
                    lastBelowCell = True
                else:
                    lastBelowCell = False

                processedCells[belowCell.y() * layerWidth + belowCell.x()] = 1

    return fillRegion
Пример #42
0
class GLWidget(QOpenGLWidget):
    xRotationChanged = pyqtSignal(int)
    yRotationChanged = pyqtSignal(int)
    zRotationChanged = pyqtSignal(int)

    def __init__(self, parent=None):
        super(GLWidget, self).__init__(parent)

        self.object = 0
        self.xRot = 0
        self.yRot = 0
        self.zRot = 0

        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)

    def minimumSizeHint(self):
        return QSize(50, 50)

    def sizeHint(self):
        return QSize(400, 400)

    def setXRotation(self, angle):
        angle = self.normalizeAngle(angle)
        if angle != self.xRot:
            self.xRot = angle
            self.xRotationChanged.emit(angle)
            self.update()

    def setYRotation(self, angle):
        angle = self.normalizeAngle(angle)
        if angle != self.yRot:
            self.yRot = angle
            self.yRotationChanged.emit(angle)
            self.update()

    def setZRotation(self, angle):
        angle = self.normalizeAngle(angle)
        if angle != self.zRot:
            self.zRot = angle
            self.zRotationChanged.emit(angle)
            self.update()

    def initializeGL(self):
        self.gl = self.context().versionFunctions()
        self.gl.initializeOpenGLFunctions()

        self.setClearColor(self.trolltechPurple.darker())
        self.object = self.makeObject()
        self.gl.glShadeModel(self.gl.GL_FLAT)
        self.gl.glEnable(self.gl.GL_DEPTH_TEST)
        self.gl.glEnable(self.gl.GL_CULL_FACE)

    def paintGL(self):
        self.gl.glClear(
                self.gl.GL_COLOR_BUFFER_BIT | self.gl.GL_DEPTH_BUFFER_BIT)
        self.gl.glLoadIdentity()
        self.gl.glTranslated(0.0, 0.0, -10.0)
        self.gl.glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0)
        self.gl.glRotated(self.yRot / 16.0, 0.0, 1.0, 0.0)
        self.gl.glRotated(self.zRot / 16.0, 0.0, 0.0, 1.0)
        self.gl.glCallList(self.object)

    def resizeGL(self, width, height):
        side = min(width, height)
        if side < 0:
            return

        self.gl.glViewport((width - side) // 2, (height - side) // 2, side,
                side)

        self.gl.glMatrixMode(self.gl.GL_PROJECTION)
        self.gl.glLoadIdentity()
        self.gl.glOrtho(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0)
        self.gl.glMatrixMode(self.gl.GL_MODELVIEW)

    def mousePressEvent(self, event):
        self.lastPos = event.pos()

    def mouseMoveEvent(self, event):
        dx = event.x() - self.lastPos.x()
        dy = event.y() - self.lastPos.y()

        if event.buttons() & Qt.LeftButton:
            self.setXRotation(self.xRot + 8 * dy)
            self.setYRotation(self.yRot + 8 * dx)
        elif event.buttons() & Qt.RightButton:
            self.setXRotation(self.xRot + 8 * dy)
            self.setZRotation(self.zRot + 8 * dx)

        self.lastPos = event.pos()

    def makeObject(self):
        genList = self.gl.glGenLists(1)
        self.gl.glNewList(genList, self.gl.GL_COMPILE)

        self.gl.glBegin(self.gl.GL_QUADS)

        x1 = +0.06
        y1 = -0.14
        x2 = +0.14
        y2 = -0.06
        x3 = +0.08
        y3 = +0.00
        x4 = +0.30
        y4 = +0.22

        self.quad(x1, y1, x2, y2, y2, x2, y1, x1)
        self.quad(x3, y3, x4, y4, y4, x4, y3, x3)

        self.extrude(x1, y1, x2, y2)
        self.extrude(x2, y2, y2, x2)
        self.extrude(y2, x2, y1, x1)
        self.extrude(y1, x1, x1, y1)
        self.extrude(x3, y3, x4, y4)
        self.extrude(x4, y4, y4, x4)
        self.extrude(y4, x4, y3, x3)

        NumSectors = 200

        for i in range(NumSectors):
            angle1 = (i * 2 * math.pi) / NumSectors
            x5 = 0.30 * math.sin(angle1)
            y5 = 0.30 * math.cos(angle1)
            x6 = 0.20 * math.sin(angle1)
            y6 = 0.20 * math.cos(angle1)

            angle2 = ((i + 1) * 2 * math.pi) / NumSectors
            x7 = 0.20 * math.sin(angle2)
            y7 = 0.20 * math.cos(angle2)
            x8 = 0.30 * math.sin(angle2)
            y8 = 0.30 * math.cos(angle2)

            self.quad(x5, y5, x6, y6, x7, y7, x8, y8)

            self.extrude(x6, y6, x7, y7)
            self.extrude(x8, y8, x5, y5)

        self.gl.glEnd()
        self.gl.glEndList()

        return genList

    def quad(self, x1, y1, x2, y2, x3, y3, x4, y4):
        self.setColor(self.trolltechGreen)

        self.gl.glVertex3d(x1, y1, -0.05)
        self.gl.glVertex3d(x2, y2, -0.05)
        self.gl.glVertex3d(x3, y3, -0.05)
        self.gl.glVertex3d(x4, y4, -0.05)

        self.gl.glVertex3d(x4, y4, +0.05)
        self.gl.glVertex3d(x3, y3, +0.05)
        self.gl.glVertex3d(x2, y2, +0.05)
        self.gl.glVertex3d(x1, y1, +0.05)

    def extrude(self, x1, y1, x2, y2):
        self.setColor(self.trolltechGreen.darker(250 + int(100 * x1)))

        self.gl.glVertex3d(x1, y1, +0.05)
        self.gl.glVertex3d(x2, y2, +0.05)
        self.gl.glVertex3d(x2, y2, -0.05)
        self.gl.glVertex3d(x1, y1, -0.05)

    def normalizeAngle(self, angle):
        while angle < 0:
            angle += 360 * 16
        while angle > 360 * 16:
            angle -= 360 * 16
        return angle

    def setClearColor(self, c):
        self.gl.glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF())

    def setColor(self, c):
        self.gl.glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF())
Пример #43
0
    def mouseMoveEvent(self, event: QMouseEvent):
        if self.scene() is None:
            return

        cursor = self.cursor().shape()

        if self.grab_start is not None:
            move = self.grab_start.x() - event.pos().x()
            self.horizontalScrollBar().setValue(
                self.horizontalScrollBar().value() + move)
            self.grab_start = event.pos()
            return

        if self.separation_area_moving:
            y_sep = self.mapToScene(event.pos()).y()
            y = self.sceneRect().y()
            h = self.sceneRect().height()
            if y < y_sep < y + h:
                self.scene().draw_sep_area(y_sep)
                self.sep_area_moving.emit(y_sep)
        elif self.is_pos_in_separea(self.mapToScene(event.pos())):
            self.setCursor(Qt.SplitVCursor)
        elif cursor == Qt.SplitVCursor:
            self.unsetCursor()

        if self.selection_area.finished and not self.selection_area.resizing:
            pos = self.mapToScene(event.pos())
            roi_edge = self.selection_area.get_selected_edge(
                pos,
                self.view_rect().width())
            if roi_edge is None and cursor == Qt.SplitHCursor:
                self.unsetCursor()
                return
            elif roi_edge == 0 or roi_edge == 1:
                self.setCursor(Qt.SplitHCursor)

        if event.buttons() == Qt.LeftButton and self.selection_area.resizing:

            if self.selection_area.selected_edge == 0:
                start = self.mapToScene(event.pos())
                self.set_selection_area(x=start.x())
                self.scroll_mouse(start.x())
                return

            if self.selection_area.selected_edge == 1:
                start = QPoint(self.selection_area.rect().x(),
                               self.selection_area.rect().y())
                end = self.mapToScene(event.pos())

                self.set_selection_area(w=end.x() - start.x())
                self.scroll_mouse(end.x())
                return

        if self.mouse_press_pos is None:
            return

        self.mouse_pos = event.pos()
        if event.buttons(
        ) == Qt.LeftButton and not self.selection_area.finished:
            start = self.mapToScene(self.mouse_press_pos)
            end = self.mapToScene(self.mouse_pos)
            self.set_selection_area(w=end.x() - start.x())
            self.scroll_mouse(end.x())
Пример #44
0
class TileSelectionTool(AbstractTileTool):

    def __init__(self, parent = None):
        super().__init__(self.tr("Rectangular Select"),
                           QIcon(":images/22x22/stock-tool-rect-select.png"),
                           QKeySequence(self.tr("R")),
                           parent)
        self.mSelectionMode = SelectionMode.Replace
        self.mSelecting = False

        self.setTilePositionMethod(TilePositionMethod.BetweenTiles)

        self.mSelectionStart = QPoint()

    def tr(self, sourceText, disambiguation = '', n = -1):
        return QCoreApplication.translate('TileSelectionTool', sourceText, disambiguation, n)

    def mousePressed(self, event):
        button = event.button()
        modifiers = event.modifiers()
        if (button == Qt.LeftButton):
            if (modifiers == Qt.ControlModifier):
                self.mSelectionMode = SelectionMode.Subtract
            elif (modifiers == Qt.ShiftModifier):
                self.mSelectionMode = SelectionMode.Add
            elif (modifiers == (Qt.ControlModifier | Qt.ShiftModifier)):
                self.mSelectionMode = SelectionMode.Intersect
            else:
                self.mSelectionMode = SelectionMode.Replace

            self.mSelecting = True
            self.mSelectionStart = self.tilePosition()
            self.brushItem().setTileRegion(QRegion())

    def mouseReleased(self, event):
        if (event.button() == Qt.LeftButton):
            self.mSelecting = False
            document = self.mapDocument()
            selection = document.selectedArea()
            area = self.selectedArea()
            x = self.mSelectionMode
            if x==SelectionMode.Replace:
                selection = area
            elif x==SelectionMode.Add:
                selection += area
            elif x==SelectionMode.Subtract:
                selection = selection.xored(QRegion(area))
            elif x==SelectionMode.Intersect:
                selection &= area

            if (selection != document.selectedArea()):
                cmd = ChangeSelectedArea(document, selection)
                document.undoStack().push(cmd)

            self.brushItem().setTileRegion(QRegion())
            self.updateStatusInfo()

    def languageChanged(self):
        self.setName(self.tr("Rectangular Select"))
        self.setShortcut(QKeySequence(self.tr("R")))

    def tilePositionChanged(self, tilePos):
        if (self.mSelecting):
            self.brushItem().setTileRegion(self.selectedArea())

    def updateStatusInfo(self):
        if (not self.isBrushVisible() or not self.mSelecting):
            super().updateStatusInfo()
            return

        pos = self.tilePosition()
        area = self.selectedArea()
        self.setStatusInfo(self.tr("%d, %d - Rectangle: (%d x %d)"%((pos.x()), pos.y(), area.width(), area.height())))

    def selectedArea(self):
        tilePos = self.tilePosition()
        pos = QPoint(min(tilePos.x(), self.mSelectionStart.x()), min(tilePos.y(), self.mSelectionStart.y()))
        size = QSize(abs(tilePos.x() - self.mSelectionStart.x()), abs(tilePos.y() - self.mSelectionStart.y()))
        return QRect(pos, size)
Пример #45
0
 def move(self, pos):
     # make new pos to center
     pos = QPoint(pos.x() - self.width() * 0.5, pos.y() - self.height() * 0.5)
     # make this always on top
     self.raise_()
     QWidget.move(self, pos)
Пример #46
0
class Overlay(QWidget):

    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 insideSelection(self, point):
        width = self.last_position.x() - self.start_position.x()
        height = self.last_position.y() - self.start_position.y()

        return (    point.x() > self.start_position.x() and point.x() < self.start_position.x() + width and
                    point.y() > self.start_position.y() and point.y() < self.start_position.y() + height    )

    def mouseMoveEvent(self, event):

        if self.on_selection:
            self.last_position = event.pos()
            self.update()

    def mousePressEvent(self, QMouseEvent):

        if not self.insideSelection(QMouseEvent.pos()):
            self.on_selection = True
            self.selected = True
            self.start_position = QMouseEvent.pos()
            self.last_position = QMouseEvent.pos()
            self.update()

    def mouseDoubleClickEvent(self, QMouseEvent):
        if self.insideSelection(QMouseEvent.pos()):
            width = self.last_position.x() - self.start_position.x()
            height = self.last_position.y() - self.start_position.y()
            self.c.cropImage.emit(self.start_position.x(), self.start_position.y(), width,height)

    def mouseReleaseEvent(self, QMouseEvent):
        self.on_selection = False
        self.update()

    def enterEvent(self, event):
        return super().enterEvent(event)

    def leaveEvent(self, event):
        return super().enterEvent(event)

    def paintEvent(self, e):
        qp = QPainter()
        qp.begin(self)
        #self.drawWidget(qp)
        if self.selected:
            qp.setCompositionMode(QPainter.CompositionMode_HardLight)
            qp.setBrush(QColor(0, 0, 0, 128))
            qp.drawRect(0,0, self.width(), self.height())
            qp.setCompositionMode(QPainter.CompositionMode_Overlay)
            qp.setBrush(QColor(255, 255, 255, 255))

            width = self.last_position.x() - self.start_position.x()
            height = self.last_position.y()-self.start_position.y()

            qp.drawRect(self.start_position.x(), self.start_position.y(), width, height)
            qp.setCompositionMode(QPainter.CompositionMode_SourceOver)

            image_w = min([abs(width), abs(height), self.crop.width()]) #self.crop.width()
            image_h = image_w #self.crop.height()
            qp.drawPixmap(self.start_position.x() + width/2 - image_w/2, self.start_position.y() + height/2 - image_h/2, image_w, image_h, self.crop)

        qp.end()
Пример #47
0
    class ScribbleArea(QWidget):
        def __init__(self, width, height, scaling_factor, foreground_color, background_color, enable_grid, grid_color, parent):
            super().__init__(parent)

            self.parent = parent
            self.scribbling = 0

            self.width = width
            self.height = height
            self.scaling_factor = scaling_factor
            self.pen_width = 1
            self.foreground_color = foreground_color
            self.background_color = background_color
            self.grid_enabled = enable_grid

            if grid_color is not None:
                self.grid_color = grid_color
            else:
                self.grid_color = self.palette().color(QPalette.Window)

            self.image = QImage(QSize(width, height), QImage.Format_RGB32)

            self.setFixedSize(width*self.scaling_factor, height*self.scaling_factor)
            self.last_point = QPoint()
            self.clear_image()

        def set_foreground_color(self, color):
            self.foreground_color = color

        def array_draw(self, r, g, b, scale=1):
            for i in range(len(r)):
                self.image.setPixel(QPoint(i%self.width, i//self.width), (r[i]*scale << 16) | (g[i]*scale << 8) | b[i]*scale)

            self.update()

        def fill_image(self, color):
            self.image.fill(color)
            self.update()

        def clear_image(self):
            self.image.fill(self.background_color)
            self.update()

        def mousePressEvent(self, event):
            self.parent.scribbling_started.emit()

            if event.button() == Qt.LeftButton:
                self.last_point = event.pos()
                self.scribbling = 1
            elif event.button() == Qt.RightButton:
                self.last_point = event.pos()
                self.scribbling = 2

        def mouseMoveEvent(self, event):
            if (event.buttons() & Qt.LeftButton) and self.scribbling == 1:
                self.draw_line_to(event.pos())
            elif (event.buttons() & Qt.RightButton) and self.scribbling == 2:
                self.draw_line_to(event.pos())

        def mouseReleaseEvent(self, event):
            if event.button() == Qt.LeftButton and self.scribbling == 1:
                self.draw_line_to(event.pos())
                self.scribbling = 0
            elif event.button() == Qt.RightButton and self.scribbling == 2:
                self.draw_line_to(event.pos())
                self.scribbling = 0

        def paintEvent(self, event):
            painter = QPainter(self)
            painter.drawImage(QRect(0, 0, super().width(), super().height()), self.image)

            if self.grid_enabled:
                painter.setPen(QPen(self.grid_color))

                for x in range(1, self.width):
                    painter.drawLine(x * self.scaling_factor, 0, x * self.scaling_factor, super().height())

                for y in range(1, self.height):
                    painter.drawLine(0, y * self.scaling_factor, super().width(), y * self.scaling_factor)

            self.parent.paint_overlay(event, painter)

        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)
Пример #48
0
class MandelbrotWidget(QWidget):
    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 paintEvent(self, event):
        painter = QPainter(self)
        painter.fillRect(self.rect(), Qt.black)

        if self.pixmap.isNull():
            painter.setPen(Qt.white)
            painter.drawText(self.rect(), Qt.AlignCenter,
                    "Rendering initial image, please wait...")
            return

        if self.curScale == self.pixmapScale:
            painter.drawPixmap(self.pixmapOffset, self.pixmap)
        else:
            scaleFactor = self.pixmapScale / self.curScale
            newWidth = int(self.pixmap.width() * scaleFactor)
            newHeight = int(self.pixmap.height() * scaleFactor)
            newX = self.pixmapOffset.x() + (self.pixmap.width() - newWidth) / 2
            newY = self.pixmapOffset.y() + (self.pixmap.height() - newHeight) / 2

            painter.save()
            painter.translate(newX, newY)
            painter.scale(scaleFactor, scaleFactor)
            exposed, _ = painter.matrix().inverted()
            exposed = exposed.mapRect(self.rect()).adjusted(-1, -1, 1, 1)
            painter.drawPixmap(exposed, self.pixmap, exposed)
            painter.restore()

        text = "Use mouse wheel or the '+' and '-' keys to zoom. Press and " \
                "hold left mouse button to scroll."
        metrics = painter.fontMetrics()
        textWidth = metrics.width(text)

        painter.setPen(Qt.NoPen)
        painter.setBrush(QColor(0, 0, 0, 127))
        painter.drawRect((self.width() - textWidth) / 2 - 5, 0, textWidth + 10,
                metrics.lineSpacing() + 5)
        painter.setPen(Qt.white)
        painter.drawText((self.width() - textWidth) / 2,
                metrics.leading() + metrics.ascent(), text)

    def resizeEvent(self, event):
        self.thread.render(self.centerX, self.centerY, self.curScale,
                self.size())

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Plus:
            self.zoom(ZoomInFactor)
        elif event.key() == Qt.Key_Minus:
            self.zoom(ZoomOutFactor)
        elif event.key() == Qt.Key_Left:
            self.scroll(-ScrollStep, 0)
        elif event.key() == Qt.Key_Right:
            self.scroll(+ScrollStep, 0)
        elif event.key() == Qt.Key_Down:
            self.scroll(0, -ScrollStep)
        elif event.key() == Qt.Key_Up:
            self.scroll(0, +ScrollStep)
        else:
            super(MandelbrotWidget, self).keyPressEvent(event)

    def wheelEvent(self, event):
        numDegrees = event.angleDelta().y() / 8
        numSteps = numDegrees / 15.0
        self.zoom(pow(ZoomInFactor, numSteps))

    def mousePressEvent(self, event):
        if event.buttons() == Qt.LeftButton:
            self.lastDragPos = QPoint(event.pos())

    def mouseMoveEvent(self, event):
        if event.buttons() & Qt.LeftButton:
            self.pixmapOffset += event.pos() - self.lastDragPos
            self.lastDragPos = QPoint(event.pos())
            self.update()

    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 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 zoom(self, zoomFactor):
        self.curScale *= zoomFactor
        self.update()
        self.thread.render(self.centerX, self.centerY, self.curScale,
                self.size())

    def scroll(self, deltaX, deltaY):
        self.centerX += deltaX * self.curScale
        self.centerY += deltaY * self.curScale
        self.update()
        self.thread.render(self.centerX, self.centerY, self.curScale,
                self.size())
Пример #49
0
class Settings(object):

    l = logging.getLogger('Settings')


    def __init__(self, fileName = 'notepad.ini'):
        self.fileName = fileName
        self.notepads = []
        self.mainWindowSize = QSize(1200, 700)
        self.mainWindowPos = QPoint(240, 200)
        self.browserPath = []

    
    def load(self):
        self.l.debug('Loading local settings ...')
        config = configparser.ConfigParser()
        config.read(self.fileName)

        # load dropbox configuration
        self.dropboxToken = ''
        if config.has_section('dropbox'):
            self.dropboxToken = config['dropbox'].get('dropboxToken')

        # load browser state
        if config.has_section('browser'):
            browserSettings = config['browser']
            path = browserSettings.get('path')
            self.browserPath = ast.literal_eval(path)

        # load main window position and size
        if config.has_section('mainWindow'):
            windowSettings = config['mainWindow']

            # read position
            pos = windowSettings.get('pos', '{},{}'.format(self.mainWindowPos.x(), self.mainWindowPos.y())).split(',')
            self.mainWindowPos = QPoint(int(pos[0]), int(pos[1]))

            # read size
            size = windowSettings.get('size', '{},{}'.format(self.mainWindowSize.width(), self.mainWindowSize.height())).split(',')
            self.mainWindowSize = QSize(int(size[0]), int(size[1]))

        # load notepads
        self.notepads = []
        for s in config.sections():
            if s.startswith('notepad_'):
                npDef = None
                npType = config.get(s, 'type')
                if npType == 'local':
                    npDef = {'name' : config.get(s, 'name'),
                             'type'  : npType,
                             'path'   : config.get(s, 'path') }
                elif npType == 'dropbox':
                    npDef = {'name' : config.get(s, 'name'),
                             'type'  : npType }
                if npDef is not None:
                    self.notepads.append(npDef)


    def dump(self, channel):
        self.l.debug('Saving local settings ...')
        config = configparser.ConfigParser()

        config.add_section('dropbox')
        config.set('dropbox', 'dropboxToken', self.dropboxToken)

        config.add_section('browser')
        config.set('browser', 'path', str(self.browserPath))

        config.add_section('mainWindow')
        config.set('mainWindow', 'pos', '{},{}'.format(self.mainWindowPos.x(), self.mainWindowPos.y()))
        config.set('mainWindow', 'size', '{},{}'.format(self.mainWindowSize.width(), self.mainWindowSize.height()))

        idx = 0
        for s in self.notepads:
            sectName = "notepad_{}".format(idx)
            idx += 1
            
            config.add_section(sectName)
            config.set(sectName, 'name', s['name'])
            config.set(sectName, 'type', s['type'])
            if s['type'] == 'local':
                config.set(sectName, 'path', s['path'])

        config.write(channel)

    
    def save(self):
        with open(self.fileName, 'w') as configfile:
            self.dump(configfile)


    def getNotepads(self):
        return self.notepads

    def addNotepad(self, npDef):
        self.notepads.append(npDef)

    def setMainWindowPos(self, pos):
        self.mainWindowPos = pos    

    def setBrowserPath(self, path):
        self.browserPath = path

    def setMainWindowSize(self, size):
        self.mainWindowSize = size

    def getMainWindowPos(self):
        return self.mainWindowPos

    def getMainWindowSize(self):
        return self.mainWindowSize

    def getBrowserPath(self):
        return self.browserPath

    def getDropboxToken(self):
        return self.dropboxToken 

    def setDropboxToken(self, token):
        self.dropboxToken = token 
Пример #50
0
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
Пример #51
0
    def mouseMoveEvent(self, event: QMouseEvent):
        if self.scene() is None:
            return

        cursor = self.cursor().shape()

        if self.grab_start is not None:
            move_x = self.grab_start.x() - event.pos().x()
            self.horizontalScrollBar().setValue(
                self.horizontalScrollBar().value() + move_x)

            if self.move_y_with_drag:
                move_y = self.grab_start.y() - event.pos().y()
                self.verticalScrollBar().setValue(
                    self.verticalScrollBar().value() + move_y)

            self.grab_start = event.pos()
            return

        if self.separation_area_moving:
            y_sep = self.mapToScene(event.pos()).y()
            y = self.sceneRect().y()
            h = self.sceneRect().height()
            if y < y_sep < y + h:
                self.scene().draw_sep_area(y_sep, show_symbols=True)
                self.sep_area_moving.emit(y_sep)
        elif self.is_pos_in_separea(self.mapToScene(event.pos())):
            self.setCursor(Qt.SplitVCursor)
        elif cursor == Qt.SplitVCursor and self.has_horizontal_selection:
            self.unsetCursor()

        if self.selection_area.finished and not self.selection_area.resizing:
            pos = self.mapToScene(event.pos())
            roi_edge = self.selection_area.get_selected_edge(
                pos, self.transform())
            if roi_edge is None:
                if (cursor == Qt.SplitHCursor and self.has_horizontal_selection) \
                        or (cursor == Qt.SplitVCursor and not self.has_horizontal_selection):
                    self.unsetCursor()
                    return
            elif roi_edge == 0 or roi_edge == 1:
                if self.has_horizontal_selection:
                    self.setCursor(Qt.SplitHCursor)
                else:
                    self.setCursor(Qt.SplitVCursor)

        if event.buttons() == Qt.LeftButton and self.selection_area.resizing:

            if self.selection_area.selected_edge == 0:
                start = self.mapToScene(event.pos())
                self.__set_selection_area(x=start.x(), y=start.y())
                if self.has_horizontal_selection:
                    self.scroll_mouse(start.x())
                return

            if self.selection_area.selected_edge == 1:
                start = QPoint(self.selection_area.x, self.selection_area.y)
                end = self.mapToScene(event.pos())

                self.__set_selection_area(w=end.x() - start.x(),
                                          h=end.y() - start.y())

                if self.has_horizontal_selection:
                    self.scroll_mouse(end.x())

                return

        if self.mouse_press_pos is None:
            return

        self.mouse_pos = event.pos()
        if event.buttons(
        ) == Qt.LeftButton and not self.selection_area.finished:
            start = self.mapToScene(self.mouse_press_pos)
            end = self.mapToScene(self.mouse_pos)
            self.__set_selection_area(w=end.x() - start.x(),
                                      h=end.y() - start.y())
            if self.has_horizontal_selection:
                self.scroll_mouse(end.x())
Пример #52
0
 def mouseMoveEvent(self, event):
     delta = QPoint(event.globalPos() - self.prev_pos)
     self.move(self.x() + delta.x(), self.y() + delta.y())
     self.prev_pos = event.globalPos()
Пример #53
0
class Settings(object):

    l = logging.getLogger('Settings')


    def __init__(self, fileName = 'shadow.ini'):
        self.fileName = fileName
        self.tzIdx = 0
        self.mainWindowSize = QSize(1200, 700)
        self.mainWindowPos = QPoint(240, 200)

    def load(self):
        self.l.debug('Loading local settings from {}'.format(self.fileName))
        config = configparser.ConfigParser()
        config.read(self.fileName)

        if config.has_section('common'):
            commonSettings = config['common']
            self.tzIdx = int(commonSettings.get('tz', 0))

        # load main window position and size
        if config.has_section('mainWindow'):
            windowSettings = config['mainWindow']

            # read position
            pos = windowSettings.get('pos', '{},{}'.format(self.mainWindowPos.x(), self.mainWindowPos.y())).split(',')
            self.mainWindowPos = QPoint(int(pos[0]), int(pos[1]))

            # read size
            size = windowSettings.get('size', '{},{}'.format(self.mainWindowSize.width(), self.mainWindowSize.height())).split(',')
            self.mainWindowSize = QSize(int(size[0]), int(size[1]))

        

    def dump(self, channel):
        self.l.debug('Saving local settings ...')
        config = configparser.ConfigParser()

        config.add_section('common')
        config.set('common', 'tz', str(self.tzIdx))

        config.add_section('mainWindow')
        config.set('mainWindow', 'pos', '{},{}'.format(self.mainWindowPos.x(), self.mainWindowPos.y()))
        config.set('mainWindow', 'size', '{},{}'.format(self.mainWindowSize.width(), self.mainWindowSize.height()))

        config.write(channel)

    
    def save(self):
        with open(self.fileName, 'w') as configfile:
            self.dump(configfile)

    def setMainWindowPos(self, pos):
        self.mainWindowPos = pos    

    def setMainWindowSize(self, size):
        self.mainWindowSize = size

    def getMainWindowPos(self):
        return self.mainWindowPos

    def getMainWindowSize(self):
        return self.mainWindowSize

    def getTzIndex(self):
        return self.tzIdx

    def setTzIdx(self, idx):
        self.tzIdx = idx
Пример #54
0
 def move(self, target: QtCore.QPoint):
     self.move_animation.setStartValue(self.getGeometry())
     self.move_animation.setEndValue(
         QtCore.QRect(target.x(), target.y(), self._width, self._height))
     self.move_animation.start()
Пример #55
0
	def paintEvent(self, event):
		  
		painter = QPainter(self)
		painter.setPen(self.pen)
		painter.setBrush(self.brush)
		if self.antialiased:
			painter.setRenderHint(QPainter.Antialiasing)

		angle_step = 360 / self.n_states

		painter.save()	#Save_1. Save the state of the system (push matrix)
		painter.translate(self.dist_center.x(), self.dist_center.y())		# go to the center of the render area
		painter.rotate(-180)	#to start painting from the left side of the circle (clockwise)

		#center of the circumference where through we are going to paint our states 
		x = self.dist_radius * math.cos(0)	
		y = self.dist_radius * math.sin(0)


		for h in range(self.n_states):

			rot = angle_step * h 	# each state is equidistant from the others. We paint them in circles

			painter.save()			#Save_2
			painter.rotate(rot)		#now our system is pointing to the next state to be drawn
			painter.translate(x,y)	#now our origin is in the center of the next state to be drawn

			#if the state is active, fill it green
			if self.machine.getState(h).isActive():	
				painter.setBrush(self.greenGradientBrush)			
			painter.drawEllipse(QPoint(0,0), self.state_radius, self.state_radius)	#draw the new state

			#global position of transformed coordinates (before any transformation, origin at top-left corner)
			gx = painter.worldTransform().map(QPoint(0,0)).x()
			gy = painter.worldTransform().map(QPoint(0,0)).y()
			self.machine.getState(h).setPos(gx, gy)		#store the center of the state without any transformation applied

			# text transformation. Our origin is still in the center of the current state
			painter.save()			#Save_3
			painter.rotate(180)		#making the text go vertical
			painter.rotate(-rot)	#undoing the rotation made for painting the state. No the text is horizontal
			font = painter.font();
			font.setPixelSize(self.state_radius*.4);
			painter.setFont(font);
			rect = QRect(-self.state_radius, -self.state_radius, self.state_radius*2, self.state_radius*2)
			painter.drawText(rect, Qt.AlignCenter, self.machine.getState(h).getName());
			painter.restore()	#Restore_3
			#end text transformation

			painter.restore()	#Restore_2
			
		painter.restore()	#Restore_1. Restore the state of the system (pop matrix)

		
		#drawing transitions. Line between states
		painter.save()	# Save_4
		pptv = QTransform()		#Define a new transformation. Needed to rotate the system along other axis than Z
		pptv.translate(0, self.height())	#We are now at the bottom-left corner of the screen
		pptv.rotate(-180, Qt.XAxis)			#Rotate along the X-axis so now we are in a typical cartesian system.
		painter.setTransform(pptv)			#Apply the transformation
		states = self.machine.getStates()
		for state in states:
			transitions = state.getTransitions()
			for transition in transitions:
				#get the center of the origin and destination states in our current system state
				orig = QPoint(state.getPos()[0], state.getPos()[1])
				end = QPoint(self.machine.getState(transition.getStateEnd()).getPos()[0], self.machine.getState(transition.getStateEnd()).getPos()[1])
				# get those coordinates without transformation
				orig2 = QPoint(painter.worldTransform().map(orig))
				end2 = QPoint(painter.worldTransform().map(end))

				#get the angle between states centers and the horizon
				angle = math.atan2(end2.y() - orig2.y(), end2.x() - orig2.x())

				#get the coordinates of the starting point of the transition (it starts in the bound of the state, not in the center)
				newX = self.state_radius * math.cos(angle) + orig2.x()
				newY = self.state_radius * math.sin(angle) + orig2.y()
				#now the transition starts at the border, not in the center
				orig2.setX(newX)
				orig2.setY(newY)

				#same for the destination state
				angle2 = math.atan2(orig2.y() - end2.y(), orig2.x() - end2.x())
				newX2 = self.state_radius * math.cos(angle2) + end2.x()
				newY2 = self.state_radius * math.sin(angle2) + end2.y()
				end2.setX(newX2)
				end2.setY(newY2)

				#draw the line between the origin and destination states
				painter.drawLine(orig2, end2)
				#get the start and the end of the transition untransformed
				init = QPoint(painter.worldTransform().map(orig2))
				end = QPoint(painter.worldTransform().map(end2))
				#store that info
				transition.setOrig(init.x(), init.y())
				transition.setDest(end.x(), end.y())	
				transition.setAngle(angle)
		painter.restore() #Restore_4


		#Appliying style to the transitions
		painter.setPen(QPen(QColor(Qt.gray), 3))
		for state in self.machine.getStates():
			for transition in state.getTransitions():
				#get the start and end coordinates of the transition
				i = QPoint(transition.getOrig()[0], transition.getOrig()[1])
				o = QPoint(transition.getDest()[0], transition.getDest()[1])			
				painter.drawPolyline(i, o)

				#Drawing the arrow at the end of the transition
				painter.save()	#Save_5
				painter.setPen(QPen(QColor(Qt.gray), 2))
				painter.translate(transition.getDest()[0],transition.getDest()[1])	#Go to the end of the transition
				painter.rotate(90 - transition.getAngle()*180/math.pi)		#Rotate to point in the direction of the transition

				#coordinates of the arrow (triangle)
				a = QPoint(0,0)
				b = QPoint(-5,10)
				c = QPoint(5,10)

				#coordinates of the arrow untransformed
				a1 = painter.worldTransform().map(a)
				b1 = painter.worldTransform().map(b)
				c1 = painter.worldTransform().map(c)

				#Drawin the actual arrow
				pointer = QPolygon([a,b,c])
				painter.drawPolygon(pointer)
				painter.restore()	#Restore_5

				#For the animation of the transition
				painter.save()	#Save_6
				if transition.isActive():	#if the current transition is the active one the wave function will be running, so it's updating the canvas

					painter.setPen(QPen(QColor(Qt.green), 3))
					painter.drawPolyline(i,o)
					
					painter.setPen(QPen(QColor(Qt.gray), 3))
					painter.drawPolyline(self.poly(self.pts))

					#Draw the arrow in the active state (red arrow)
					painter.setBrush(QBrush(QColor(255, 0, 0)))
					painter.setPen(QPen(QColor(Qt.red), 2))
					pointer = QPolygon([a1,b1,c1])
					painter.drawPolygon(pointer)
					
					#Ball that follows the line animation
					for x, y in self.pts:
						painter.drawEllipse(QRectF(self.pts[0][0] - 4, self.pts[0][1] - 4, 8, 8))
				painter.restore()	#Restore_6

				#Painting the text of the transition
				painter.save()	#Save_7
				pptv = QTransform()
				painter.setPen(QPen(QColor(Qt.black), 3))
				#get the middle point of the transition
				middleX = (transition.getOrig()[0] + transition.getDest()[0]) /2	
				middleY = (transition.getOrig()[1] + transition.getDest()[1]) /2
				pptv.translate(middleX, middleY)	#translate to that point
				painter.setTransform(pptv)			#apply the transformation
				font = painter.font();
				font.setPixelSize(self.state_radius*.2);
				painter.setFont(font);
				rect = QRect(-self.state_radius, -self.state_radius, self.state_radius*2, self.state_radius*2)
				name = str(transition.getId())+ '. ' + transition.getName()
				painter.drawText(rect, Qt.AlignCenter, name)
				painter.restore()	#Restore_7


  
		#paint the actual canvas
		painter.setPen(self.palette().dark().color())
		painter.setBrush(Qt.NoBrush)
		painter.drawRect(QRect(0, 0, self.width() - 1, self.height() - 1))
Пример #56
0
	def mouseMoveEvent(self, event):
		if self.mIsPressed:
			appNewPos = QPoint()
			appNewPos.setX(QCursor.pos().x() - self.mXDiff)
			appNewPos.setY(QCursor.pos().y() - self.mYDiff)
			self.move(appNewPos.x(), appNewPos.y())
Пример #57
0
class GLWidget(QOpenGLWidget):
    xRotationChanged = pyqtSignal(int)
    yRotationChanged = pyqtSignal(int)
    zRotationChanged = pyqtSignal(int)
    zoomChanged = pyqtSignal(int)

    def __init__(self, parent=None):
        super(GLWidget, self).__init__(parent)

        self.model = None

        self.xRot = 1700
        self.yRot = 2850
        self.zRot = 0

        self.lastPos = QPoint()

        self.r_back = self.g_back = self.b_back = 0

        self.plotdata = []
        self.plotlen = 16000

        # Where we are centering.
        self.xcenter = 0.0
        self.ycenter = 0.0
        self.zcenter = 0.0

        # Where the eye is
        self.distance = 10.0

        # Field of view in y direction
        self.fovy = 30.0

        # Position of clipping planes.
        self.near = 0.1
        self.far = 1000.0

        # View settings
        self.perspective = 0
        self.lat = 0
        self.minlat = -90
        self.maxlat = 90

        # does not show HUD by default
        self.hud = Hud()
        # self.hud.show("stuff")
        # add a 100ms timer to poll linuxcnc stats
        self.timer = QTimer()
        self.timer.timeout.connect(self.update)
        self.timer.start(100)

    def getOpenglInfo(self):
        info = """
            Vendor: {0}
            Renderer: {1}
            OpenGL Version: {2}
            Shader Version: {3}
        """.format(
            GL.glGetString(GL.GL_VENDOR),
            GL.glGetString(GL.GL_RENDERER),
            GL.glGetString(GL.GL_VERSION),
            GL.glGetString(GL.GL_SHADING_LANGUAGE_VERSION)
        )

        return info

    def minimumSizeHint(self):
        return QSize(50, 50)

    def sizeHint(self):
        return QSize(400, 400)

    def winfo_width(self):
        return self.geometry().width()

    def winfo_height(self):
        return self.geometry().height()

    def setXRotation(self, angle):
        angle = self.normalizeAngle(angle)
        if angle != self.xRot:
            self.xRot = angle
            self.xRotationChanged.emit(angle)
            self.update()

    def setYRotation(self, angle):
        angle = self.normalizeAngle(angle)
        if angle != self.yRot:
            self.yRot = angle
            self.yRotationChanged.emit(angle)
            self.update()

    def setZRotation(self, angle):
        angle = self.normalizeAngle(angle)
        if angle != self.zRot:
            self.zRot = angle
            self.zRotationChanged.emit(angle)
            self.update()

    def setZoom(self, depth):
        self.distance = depth
        self.update()

    def zoomin(self):
        self.distance = self.distance / 1.1
        if self.distance < 600:
            self.distance = 600
        self.update()

    def zoomout(self):
        self.distance = self.distance * 1.1
        if self.distance > 5600:
            self.distance = 5600
        self.update()

    def set_latitudelimits(self, minlat, maxlat):
        """Set the new "latitude" limits for rotations."""

        if maxlat > 180:
            return
        if minlat < -180:
            return
        if maxlat <= minlat:
            return
        self.maxlat = maxlat
        self.minlat = minlat

    def initializeGL(self):
        # basic_lighting
        GL.glLightfv(GL.GL_LIGHT0, GL.GL_POSITION, (1, -1, .5, 0))
        GL.glLightfv(GL.GL_LIGHT0, GL.GL_AMBIENT, (.2, .2, .2, 0))
        GL.glLightfv(GL.GL_LIGHT0, GL.GL_DIFFUSE, (.6, .6, .4, 0))
        GL.glLightfv(GL.GL_LIGHT0 + 1, GL.GL_POSITION, (-1, -1, .5, 0))
        GL.glLightfv(GL.GL_LIGHT0 + 1, GL.GL_AMBIENT, (.0, .0, .0, 0))
        GL.glLightfv(GL.GL_LIGHT0 + 1, GL.GL_DIFFUSE, (.0, .0, .4, 0))
        GL.glMaterialfv(GL.GL_FRONT_AND_BACK, GL.GL_AMBIENT_AND_DIFFUSE, (1, 1, 1, 0))
        GL.glDisable(GL.GL_CULL_FACE)
        GL.glEnable(GL.GL_LIGHTING)
        GL.glEnable(GL.GL_LIGHT0)
        GL.glEnable(GL.GL_LIGHT0 + 1)
        GL.glDepthFunc(GL.GL_LESS)
        GL.glEnable(GL.GL_DEPTH_TEST)
        GL.glMatrixMode(GL.GL_MODELVIEW)
        GL.glLoadIdentity()

    def paintGL(self):
        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
        GL.glLoadIdentity()
        GL.glTranslated(0.0, 0.0, -10.0)
        GL.glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0)
        GL.glRotated(self.yRot / 16.0, 0.0, 1.0, 0.0)
        GL.glRotated(self.zRot / 16.0, 0.0, 0.0, 1.0)

        # draw Objects
        GL.glPushMatrix()  # Protect our matrix
        w = self.winfo_width()
        h = self.winfo_height()
        GL.glViewport(0, 0, w, h)

        # Clear the background and depth buffer.
        GL.glClearColor(self.r_back, self.g_back, self.b_back, 0.)
        GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)

        GL.glMatrixMode(GL.GL_PROJECTION)
        GL.glLoadIdentity()
        GLU.gluPerspective(self.fovy, float(w) / float(h), self.near, self.far)

        if 0:
            # Now translate the scene origin away from the world origin
            GL.glMatrixMode(GL.GL_MODELVIEW)
            mat = GL.glGetDoublev(GL.GL_MODELVIEW_MATRIX)
            GL.glLoadIdentity()
            GL.glTranslatef(-self.xcenter, -self.ycenter, -(self.zcenter + self.distance))
            GL.glMultMatrixd(mat)
        else:
            GLU.gluLookAt(self.xcenter, self.ycenter, self.zcenter + self.distance,
                          self.xcenter, self.ycenter, self.zcenter,
                          0., 1., 0.)
            GL.glMatrixMode(GL.GL_MODELVIEW)

        # Call objects redraw method.
        self.drawObjects()
        GL.glFlush()  # Tidy up
        GL.glPopMatrix()  # Restore the matrix

    def drawObjects(self, *args):
        if self.winfo_width() == 1: return
        if self.model is None: return

        self.model.traverse()
        # current coords: world
        # the matrices tool2view, work2view, and world2view
        # transform from tool/work/world coords to viewport coords
        # if we want to draw in tool coords, we need to do
        # "tool -> view -> world" (since the current frame is world)
        # and if we want to draw in work coords, we need
        # "work -> view -> world".  For both, we need to invert
        # the world2view matrix to do the second step
        view2world = invert(self.world2view.t)
        # likewise, for backplot, we want to transform the tooltip
        # position from tool coords (where it is [0,0,0]) to work
        # coords, so we need tool -> view -> work
        # so lets also invert the work2view matrix
        view2work = invert(self.work2view.t)

        # since backplot lines only need vertexes, not orientation,
        # and the tooltip is at the origin, getting the tool coords
        # is easy
        tx, ty, tz = self.tool2view.t[12:15]
        # now we have to transform them to the work frame
        wx = tx * view2work[0] + ty * view2work[4] + tz * view2work[8] + view2work[12]
        wy = tx * view2work[1] + ty * view2work[5] + tz * view2work[9] + view2work[13]
        wz = tx * view2work[2] + ty * view2work[6] + tz * view2work[10] + view2work[14]
        # wx, wy, wz are the values to use for backplot
        # so we save them in a buffer
        if len(self.plotdata) == self.plotlen:
            del self.plotdata[:self.plotlen / 10]
        point = [wx, wy, wz]
        if not self.plotdata or point != self.plotdata[-1]:
            self.plotdata.append(point)

        # now lets draw something in the tool coordinate system
        # GL.glPushMatrix()
        # matrixes take effect in reverse order, so the next
        # two lines do "tool -> view -> world"
        # GL.glMultMatrixd(view2world)
        # GL.glMultMatrixd(self.tool2view.t)

        # do drawing here
        # cylinder normally goes to +Z, we want it down
        # GL.glTranslatef(0,0,-60)
        # GLU.gluCylinder(self.q1, 20, 20, 60, 32, 16)

        # back to world coords
        # GL.glPopMatrix()

        # we can also draw in the work coord system
        GL.glPushMatrix()
        # "work -> view -> world"
        GL.glMultMatrixd(view2world)
        GL.glMultMatrixd(self.work2view.t)
        # now we can draw in work coords, and whatever we draw
        # will move with the work, (if the work is attached to
        # a table or indexer or something that moves with
        # respect to the world

        # just a test object, sitting on the table
        # GLU.gluCylinder(self.q2, 40, 20, 60, 32, 16)

        # draw head up display
        if (hasattr(self.hud, "draw")):
            self.hud.draw()

        # draw backplot
        GL.glDisable(GL.GL_LIGHTING)
        GL.glLineWidth(2)
        GL.glColor3f(1.0, 0.5, 0.5)

        GL.glBegin(GL.GL_LINE_STRIP)
        for p in self.plotdata:
            GL.glVertex3f(*p)
        GL.glEnd()

        GL.glEnable(GL.GL_LIGHTING)
        GL.glColor3f(1, 1, 1)
        GL.glLineWidth(1)
        GL.glDisable(GL.GL_BLEND)
        GL.glDepthFunc(GL.GL_LESS)

        # back to world again
        GL.glPopMatrix()

    def plotclear(self):
        del self.plotdata[:self.plotlen]

    def resizeGL(self, width, height):
        side = min(width, height)
        if side < 0:
            return

        GL.glViewport((width - side) // 2, (height - side) // 2, side,
                      side)

        GL.glMatrixMode(GL.GL_PROJECTION)
        GL.glLoadIdentity()
        GL.glOrtho(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0)
        GL.glMatrixMode(GL.GL_MODELVIEW)

    def mousePressEvent(self, event):
        self.lastPos = event.pos()

    def mouseMoveEvent(self, event):
        dx = event.x() - self.lastPos.x()
        dy = event.y() - self.lastPos.y()

        if event.buttons() & Qt.LeftButton:
            self.setXRotation(self.xRot + 8 * dy)
            self.setYRotation(self.yRot + 8 * dx)
        elif event.buttons() & Qt.RightButton:
            self.setXRotation(self.xRot + 8 * dy)
            self.setZRotation(self.zRot + 8 * dx)

        self.lastPos = event.pos()

    def mouseDoubleClickEvent(self, event):
        if event.button() & Qt.RightButton:
            self.plotclear()

    def wheelEvent(self, event):
        # Use the mouse wheel to zoom in/out
        a = event.angleDelta().y() / 200
        if a < 0:
            self.zoomout()
        else:
            self.zoomin()
        event.accept()

    def normalizeAngle(self, angle):
        while angle < 0:
            angle += 360 * 16
        while angle > 360 * 16:
            angle -= 360 * 16
        return angle
Пример #58
0
    def __drawTool(self, pos, mark):
        """
        Private method to perform a draw operation depending of the current
        tool.
        
        @param pos widget coordinate to perform the draw operation at (QPoint)
        @param mark flag indicating a mark operation (boolean)
        @return flag indicating a successful draw (boolean)
        """
        self.__unMark()

        if mark:
            self.__endPos = QPoint(pos)
            drawColor = self.MarkColor
            img = self.__markImage
        else:
            drawColor = self.penColor()
            img = self.__image

        start = QPoint(*self.__imageCoordinates(self.__startPos))
        end = QPoint(*self.__imageCoordinates(pos))

        painter = QPainter(img)
        painter.setPen(drawColor)
        painter.setCompositionMode(self.__compositingMode)

        if self.__curTool == self.Line:
            painter.drawLine(start, end)

        elif self.__curTool in [
                self.Rectangle, self.FilledRectangle, self.RectangleSelection
        ]:
            left = min(start.x(), end.x())
            top = min(start.y(), end.y())
            right = max(start.x(), end.x())
            bottom = max(start.y(), end.y())
            if self.__curTool == self.RectangleSelection:
                painter.setBrush(QBrush(drawColor))
            if self.__curTool == self.FilledRectangle:
                for y in range(top, bottom + 1):
                    painter.drawLine(left, y, right, y)
            else:
                painter.drawRect(left, top, right - left, bottom - top)
            if self.__selecting:
                self.__selRect = QRect(left, top, right - left + 1,
                                       bottom - top + 1)
                self.__selectionAvailable = True
                self.selectionAvailable.emit(True)

        elif self.__curTool in [
                self.Circle, self.FilledCircle, self.CircleSelection
        ]:
            r = max(abs(start.x() - end.x()), abs(start.y() - end.y()))
            if self.__curTool in [self.FilledCircle, self.CircleSelection]:
                painter.setBrush(QBrush(drawColor))
            painter.drawEllipse(start, r, r)
            if self.__selecting:
                self.__selRect = QRect(start.x() - r,
                                       start.y() - r, 2 * r + 1, 2 * r + 1)
                self.__selectionAvailable = True
                self.selectionAvailable.emit(True)

        elif self.__curTool in [self.Ellipse, self.FilledEllipse]:
            r1 = abs(start.x() - end.x())
            r2 = abs(start.y() - end.y())
            if r1 == 0 or r2 == 0:
                return False
            if self.__curTool == self.FilledEllipse:
                painter.setBrush(QBrush(drawColor))
            painter.drawEllipse(start, r1, r2)

        painter.end()

        if self.__curTool in [
                self.Circle, self.FilledCircle, self.Ellipse,
                self.FilledEllipse
        ]:
            self.update()
        else:
            self.__updateRect(self.__startPos, pos)

        return True
Пример #59
0
class GLWidget(QOpenGLWidget):
    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 setXRotation(self, angle):
        angle = self.normalizeAngle(angle)
        if angle != self.xRot:
            self.xRot = angle

    def setYRotation(self, angle):
        angle = self.normalizeAngle(angle)
        if angle != self.yRot:
            self.yRot = angle

    def setZRotation(self, angle):
        angle = self.normalizeAngle(angle)
        if angle != self.zRot:
            self.zRot = angle

    def initializeGL(self):
        self.gl = self.context().versionFunctions()
        self.gl.initializeOpenGLFunctions()

        self.object = self.makeObject()

    def mousePressEvent(self, event):
        self.lastPos = event.pos()

    def mouseMoveEvent(self, event):
        dx = event.x() - self.lastPos.x()
        dy = event.y() - self.lastPos.y()

        if event.buttons() & Qt.LeftButton:
            self.setXRotation(self.xRot + 8 * dy)
            self.setYRotation(self.yRot + 8 * dx)
        elif event.buttons() & Qt.RightButton:
            self.setXRotation(self.xRot + 8 * dy)
            self.setZRotation(self.zRot + 8 * dx)

        self.lastPos = event.pos()

    def paintEvent(self, event):
        self.makeCurrent()

        self.gl.glMatrixMode(self.gl.GL_MODELVIEW)
        self.gl.glPushMatrix()

        self.setClearColor(self.trolltechPurple.darker())
        self.gl.glShadeModel(self.gl.GL_SMOOTH)
        self.gl.glEnable(self.gl.GL_DEPTH_TEST)
        #self.gl.glEnable(self.gl.GL_CULL_FACE)
        self.gl.glEnable(self.gl.GL_LIGHTING)
        self.gl.glEnable(self.gl.GL_LIGHT0)
        self.gl.glEnable(self.gl.GL_MULTISAMPLE)
        self.gl.glLightfv(self.gl.GL_LIGHT0, self.gl.GL_POSITION,
                (0.5, 5.0, 7.0, 1.0))

        self.setupViewport(self.width(), self.height())

        self.gl.glClear(
                self.gl.GL_COLOR_BUFFER_BIT | self.gl.GL_DEPTH_BUFFER_BIT)
        self.gl.glLoadIdentity()
        self.gl.glTranslated(0.0, 0.0, -10.0)
        self.gl.glRotated(self.xRot / 16.0, 1.0, 0.0, 0.0)
        self.gl.glRotated(self.yRot / 16.0, 0.0, 1.0, 0.0)
        self.gl.glRotated(self.zRot / 16.0, 0.0, 0.0, 1.0)
        self.gl.glCallList(self.object)

        self.gl.glMatrixMode(self.gl.GL_MODELVIEW)
        self.gl.glPopMatrix()

        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)

        for bubble in self.bubbles:
            if bubble.rect().intersects(QRectF(event.rect())):
                bubble.drawBubble(painter)

        self.drawInstructions(painter)
        painter.end()

    def resizeGL(self, width, height):
        self.setupViewport(width, height)

    def showEvent(self, event):
        self.createBubbles(20 - len(self.bubbles))

    def sizeHint(self):
        return QSize(400, 400)

    def makeObject(self):
        list = self.gl.glGenLists(1)
        self.gl.glNewList(list, self.gl.GL_COMPILE)

        self.gl.glEnable(self.gl.GL_NORMALIZE)
        self.gl.glBegin(self.gl.GL_QUADS)

        self.gl.glMaterialfv(self.gl.GL_FRONT, self.gl.GL_DIFFUSE,
                (self.trolltechGreen.red()/255.0,
                 self.trolltechGreen.green()/255.0,
                 self.trolltechGreen.blue()/255.0, 1.0))

        x1 = +0.06
        y1 = -0.14
        x2 = +0.14
        y2 = -0.06
        x3 = +0.08
        y3 = +0.00
        x4 = +0.30
        y4 = +0.22

        self.quad(x1, y1, x2, y2, y2, x2, y1, x1)
        self.quad(x3, y3, x4, y4, y4, x4, y3, x3)

        self.extrude(x1, y1, x2, y2)
        self.extrude(x2, y2, y2, x2)
        self.extrude(y2, x2, y1, x1)
        self.extrude(y1, x1, x1, y1)
        self.extrude(x3, y3, x4, y4)
        self.extrude(x4, y4, y4, x4)
        self.extrude(y4, x4, y3, x3)

        NumSectors = 200

        for i in range(NumSectors):
            angle1 = (i * 2 * math.pi) / NumSectors
            x5 = 0.30 * math.sin(angle1)
            y5 = 0.30 * math.cos(angle1)
            x6 = 0.20 * math.sin(angle1)
            y6 = 0.20 * math.cos(angle1)

            angle2 = ((i + 1) * 2 * math.pi) / NumSectors
            x7 = 0.20 * math.sin(angle2)
            y7 = 0.20 * math.cos(angle2)
            x8 = 0.30 * math.sin(angle2)
            y8 = 0.30 * math.cos(angle2)

            self.quad(x5, y5, x6, y6, x7, y7, x8, y8)

            self.extrude(x6, y6, x7, y7)
            self.extrude(x8, y8, x5, y5)

        self.gl.glEnd()

        self.gl.glEndList()
        return list

    def quad(self, x1, y1, x2, y2, x3, y3, x4, y4):
        self.gl.glNormal3d(0.0, 0.0, -1.0)
        self.gl.glVertex3d(x1, y1, -0.05)
        self.gl.glVertex3d(x2, y2, -0.05)
        self.gl.glVertex3d(x3, y3, -0.05)
        self.gl.glVertex3d(x4, y4, -0.05)

        self.gl.glNormal3d(0.0, 0.0, 1.0)
        self.gl.glVertex3d(x4, y4, +0.05)
        self.gl.glVertex3d(x3, y3, +0.05)
        self.gl.glVertex3d(x2, y2, +0.05)
        self.gl.glVertex3d(x1, y1, +0.05)

    def extrude(self, x1, y1, x2, y2):
        self.setColor(self.trolltechGreen.darker(250 + int(100 * x1)))

        self.gl.glNormal3d((x1 + x2)/2.0, (y1 + y2)/2.0, 0.0)
        self.gl.glVertex3d(x1, y1, +0.05)
        self.gl.glVertex3d(x2, y2, +0.05)
        self.gl.glVertex3d(x2, y2, -0.05)
        self.gl.glVertex3d(x1, y1, -0.05)

    def normalizeAngle(self, angle):
        while angle < 0:
            angle += 360 * 16
        while angle > 360 * 16:
            angle -= 360 * 16
        return angle

    def createBubbles(self, number):
        for i in range(number):
            position = QPointF(self.width()*(0.1 + 0.8*random.random()),
                               self.height()*(0.1 + 0.8*random.random()))
            radius = min(self.width(), self.height())*(0.0125 + 0.0875*random.random())
            velocity = QPointF(self.width()*0.0125*(-0.5 + random.random()),
                               self.height()*0.0125*(-0.5 + random.random()))

            self.bubbles.append(Bubble(position, radius, velocity))

    def animate(self):
        for bubble in self.bubbles:
            bubble.move(self.rect())

        self.update()

    def setupViewport(self, width, height):
        side = min(width, height)
        self.gl.glViewport((width - side) // 2, (height - side) // 2, side,
                side)

        self.gl.glMatrixMode(self.gl.GL_PROJECTION)
        self.gl.glLoadIdentity()
        self.gl.glOrtho(-0.5, +0.5, +0.5, -0.5, 4.0, 15.0)
        self.gl.glMatrixMode(self.gl.GL_MODELVIEW)

    def drawInstructions(self, painter):
        text = "Click and drag with the left mouse button to rotate the Qt " \
                "logo."
        metrics = QFontMetrics(self.font())
        border = max(4, metrics.leading())

        rect = metrics.boundingRect(0, 0, self.width() - 2*border,
                int(self.height()*0.125), Qt.AlignCenter | Qt.TextWordWrap,
                text)
        painter.setRenderHint(QPainter.TextAntialiasing)
        painter.fillRect(QRect(0, 0, self.width(), rect.height() + 2*border),
                QColor(0, 0, 0, 127))
        painter.setPen(Qt.white)
        painter.fillRect(QRect(0, 0, self.width(), rect.height() + 2*border),
                QColor(0, 0, 0, 127))
        painter.drawText((self.width() - rect.width())/2, border, rect.width(),
                rect.height(), Qt.AlignCenter | Qt.TextWordWrap, text)

    def setClearColor(self, c):
        self.gl.glClearColor(c.redF(), c.greenF(), c.blueF(), c.alphaF())

    def setColor(self, c):
        self.gl.glColor4f(c.redF(), c.greenF(), c.blueF(), c.alphaF())
Пример #60
0
    def paintEvent(self, _event: QPaintEvent):
        if not self.crop or not self.resolution:
            return

        painter = QPainter(self)

        # Keep a backup of the transform and create a new one
        transform = painter.worldTransform()

        # Set scaling transform
        transform = transform.scale(self.width() / self.resolution.width(),
                                    self.height() / self.resolution.height())

        # Compute the transform to flip the coordinate system on the x axis
        transform_flip = QTransform()
        if self.flip_x:
            transform_flip = transform_flip.translate(self.resolution.width(),
                                                      0.0)
            transform_flip = transform_flip.scale(-1.0, 1.0)

        # Small helper for tuple to QPoint
        def toqp(point):
            return QPoint(point[0], point[1])

        # Starting from here we care about AA
        painter.setRenderHint(QPainter.Antialiasing)

        # Draw all the QR code results
        for res in self.results:
            painter.setWorldTransform(transform_flip * transform, False)

            # Draw lines between all of the QR code points
            pen = QPen(self.qr_outline_pen)
            if res in self.validator_results.result_colors:
                pen.setColor(self.validator_results.result_colors[res])
            painter.setPen(pen)
            num_points = len(res.points)
            for i in range(0, num_points):
                i_n = i + 1

                line_from = toqp(res.points[i])
                line_from += self.crop.topLeft()

                line_to = toqp(
                    res.points[i_n] if i_n < num_points else res.points[0])
                line_to += self.crop.topLeft()

                painter.drawLine(line_from, line_to)

            # Draw the QR code data
            # Note that we reset the world transform to only the scaled transform
            # because otherwise the text could be flipped. We only use transform_flip
            # to map the center point of the result.
            painter.setWorldTransform(transform, False)
            font_metrics = painter.fontMetrics()
            data_metrics = QSize(font_metrics.horizontalAdvance(res.data),
                                 font_metrics.capHeight())

            center_pos = toqp(res.center)
            center_pos += self.crop.topLeft()
            center_pos = transform_flip.map(center_pos)

            text_offset = QPoint(data_metrics.width(), data_metrics.height())
            text_offset = text_offset / 2
            text_offset.setX(-text_offset.x())
            center_pos += text_offset

            padding = self.BG_RECT_PADDING
            bg_rect_pos = center_pos - QPoint(padding,
                                              data_metrics.height() + padding)
            bg_rect_size = data_metrics + (QSize(padding, padding) * 2)
            bg_rect = QRect(bg_rect_pos, bg_rect_size)
            bg_rect_path = QPainterPath()
            radius = self.BG_RECT_CORNER_RADIUS
            bg_rect_path.addRoundedRect(QRectF(bg_rect), radius, radius,
                                        Qt.AbsoluteSize)
            painter.setPen(self.bg_rect_pen)
            painter.fillPath(bg_rect_path, self.bg_rect_fill)
            painter.drawPath(bg_rect_path)

            painter.setPen(self.text_pen)
            painter.drawText(center_pos, res.data)