Example #1
0
   def __iniGraphicsSystem(self):   ##初始化 Graphics View系统
      self.view=QmyGraphicsView(self)   #创建图形视图组件
      self.setCentralWidget(self.view)

      self.scene=QGraphicsScene(-300,-200,600,200) #创建QGraphicsScene
      self.view.setScene(self.scene)   #与view关联

      self.view.setCursor(Qt.CrossCursor)     #设置鼠标
      self.view.setMouseTracking(True)
      self.view.setDragMode(QGraphicsView.RubberBandDrag)

      ##  4个信号与槽函数的关联
      self.view.mouseMove.connect(self.do_mouseMove)     #鼠标移动
      self.view.mouseClicked.connect(self.do_mouseClicked)   #左键按下
      self.view.mouseDoubleClick.connect(self.do_mouseDoubleClick) #鼠标双击
      self.view.keyPress.connect(self.do_keyPress)    #左键按下
Example #2
0
    def __buildUI(self):  ##构造界面
        self.resize(600, 450)
        self.setWindowTitle("Demo8_5, View/Scene/Item关系和坐标变换")

        font = self.font()
        font.setPointSize(11)
        self.setFont(font)

        centralWidget = QWidget(self)  #中间工作区组件
        vLayoutMain = QVBoxLayout(centralWidget)  #垂直布局

        groupBox = QGroupBox(centralWidget)  #显示两个Label的groupBox
        vLayoutGroup = QVBoxLayout(groupBox)
        self.__labViewSize = QLabel(groupBox)
        self.__labViewSize.setText("view坐标,左上角(0,0),宽度=,长度=")

        vLayoutGroup.addWidget(self.__labViewSize)
        self.__labSceneRect = QLabel(groupBox)
        self.__labSceneRect.setText("view.sceneRect=()")
        vLayoutGroup.addWidget(self.__labSceneRect)

        vLayoutMain.addWidget(groupBox)  #主布局添加groupBox

        self.view = QmyGraphicsView(centralWidget)  #绘图视图
        self.view.setCursor(Qt.CrossCursor)
        self.view.setMouseTracking(True)
        ##      self.view.setDragMode(QGraphicsView.RubberBandDrag)
        vLayoutMain.addWidget(self.view)  #添加到主布局

        self.setCentralWidget(centralWidget)  #设置工作区中间组件

        statusBar = QStatusBar(self)  #状态栏
        self.setStatusBar(statusBar)

        self.__labViewCord = QLabel("View 坐标:")
        self.__labViewCord.setMinimumWidth(150)
        statusBar.addWidget(self.__labViewCord)

        self.__labSceneCord = QLabel("Scene 坐标:")
        self.__labSceneCord.setMinimumWidth(150)
        statusBar.addWidget(self.__labSceneCord)

        self.__labItemCord = QLabel("Item 坐标:")
        self.__labItemCord.setMinimumWidth(150)
        statusBar.addWidget(self.__labItemCord)
Example #3
0
class QmyMainWindow(QMainWindow): 

   def __init__(self, parent=None):
      super().__init__(parent)    #调用父类构造函数,创建窗体
      self.ui=Ui_MainWindow()     #创建UI对象
      self.ui.setupUi(self)       #构造UI界面
      
      self.setWindowTitle("Demo8_6, Graphics View绘图")

      self.__buildStatusBar()    #构造状态栏
      self.__iniGraphicsSystem() #初始化 graphics View系统
      
      self.__ItemId=1   #绘图项自定义数据的key
      self.__ItemDesc=2 #绘图项自定义数据的key

      self.__seqNum=0  #每个图形项设置一个序号
      self.__backZ=0   #后置序号
      self.__frontZ=0  #前置序号

##  ==============自定义功能函数============
   def __buildStatusBar(self):   ##构造状态栏
      self.__labViewCord=QLabel("View 坐标:")
      self.__labViewCord.setMinimumWidth(150)
      self.ui.statusBar.addWidget(self.__labViewCord)

      self.__labSceneCord=QLabel("Scene 坐标:")
      self.__labSceneCord.setMinimumWidth(150)
      self.ui.statusBar.addWidget(self.__labSceneCord)

      self.__labItemCord=QLabel("Item 坐标:")
      self.__labItemCord.setMinimumWidth(150)
      self.ui.statusBar.addWidget(self.__labItemCord)

      self.__labItemInfo=QLabel("ItemInfo: ")
      self.ui.statusBar.addPermanentWidget(self.__labItemInfo)
      

   def __iniGraphicsSystem(self):   ##初始化 Graphics View系统
      self.view=QmyGraphicsView(self)   #创建图形视图组件
      self.setCentralWidget(self.view)

      self.scene=QGraphicsScene(-300,-200,600,200) #创建QGraphicsScene
      self.view.setScene(self.scene)   #与view关联

      self.view.setCursor(Qt.CrossCursor)     #设置鼠标
      self.view.setMouseTracking(True)
      self.view.setDragMode(QGraphicsView.RubberBandDrag)

      ##  4个信号与槽函数的关联
      self.view.mouseMove.connect(self.do_mouseMove)     #鼠标移动
      self.view.mouseClicked.connect(self.do_mouseClicked)   #左键按下
      self.view.mouseDoubleClick.connect(self.do_mouseDoubleClick) #鼠标双击
      self.view.keyPress.connect(self.do_keyPress)    #左键按下

   def __setItemProperties(self,item,desc):   ##item是具体类型的QGraphicsItem
      item.setFlag(QGraphicsItem.ItemIsFocusable)
      item.setFlag(QGraphicsItem.ItemIsMovable)
      item.setFlag(QGraphicsItem.ItemIsSelectable)

      self.__frontZ=1+self.__frontZ   
      item.setZValue(self.__frontZ)  #叠放次序
      item.setPos(-150+random.randint(1,200),-200+random.randint(1,200))

      self.__seqNum=1+self.__seqNum  
      item.setData(self.__ItemId,self.__seqNum) #图件编号
      item.setData(self.__ItemDesc,desc)        #图件描述

      self.scene.addItem(item)
      self.scene.clearSelection()
      item.setSelected(True)

   def __setBrushColor(self,item):  ##设置填充颜色
      color=item.brush().color()
      color=QColorDialog.getColor(color,self,"选择填充颜色")
      if color.isValid():
         item.setBrush(QBrush(color))
      
##==============event 处理函数=======================

        
##  ==========由connectSlotsByName() 自动连接的槽函数==================        
##==============创建基本图件==============
   @pyqtSlot()    ##添加一个矩形
   def on_actItem_Rect_triggered(self):
      item=QGraphicsRectItem(-50,-25,100,50)
      item.setBrush(QBrush(Qt.yellow)) #设置填充颜色
      self.__setItemProperties(item,"矩形")

   @pyqtSlot()    ##添加一个椭圆
   def on_actItem_Ellipse_triggered(self):
      item=QGraphicsEllipseItem(-50,-30,100,60) 
      item.setBrush(QBrush(Qt.blue))  #设置填充颜色
      self.__setItemProperties(item,"椭圆")

   @pyqtSlot()    ##添加一个圆
   def on_actItem_Circle_triggered(self):
      item=QGraphicsEllipseItem(-50,-50,100,100) 
      item.setBrush(QBrush(Qt.cyan))  #设置填充颜色
      self.__setItemProperties(item,"圆形")

   @pyqtSlot()    ##添加三角形
   def on_actItem_Triangle_triggered(self):
      item=QGraphicsPolygonItem()
      points=[QPointF(0,-40), QPointF(60,40), QPointF(-60,40)]
      item.setPolygon(QPolygonF(points))
      item.setBrush(QBrush(Qt.magenta))  #设置填充颜色
      self.__setItemProperties(item,"三角形")

   @pyqtSlot()    ##添加梯形
   def on_actItem_Polygon_triggered(self):
      item=QGraphicsPolygonItem()
      points=[QPointF(-40,-40), QPointF(40,-40), QPointF(100,40),QPointF(-100,40)]
      item.setPolygon(QPolygonF(points))
      item.setBrush(QBrush(Qt.green))  #设置填充颜色
      self.__setItemProperties(item,"梯形")
      
   @pyqtSlot()    ##添加直线
   def on_actItem_Line_triggered(self):
      item=QGraphicsLineItem(-100,0,100,0)
      pen=QPen(Qt.red)
      pen.setWidth(4)
      item.setPen(pen)    #设置线条属性
      self.__setItemProperties(item,"直线")
      
   @pyqtSlot()    ##添加文字
   def on_actItem_Text_triggered(self):
      strText,OK=QInputDialog.getText(self,"输入","请输入文字")
      if (not OK):
         return
      item=QGraphicsTextItem(strText)
      font=self.font()
      font.setPointSize(20)
      font.setBold(True)
      item.setFont(font)   #设置字体
      item.setDefaultTextColor(Qt.black)  #设置颜色
      self.__setItemProperties(item,"文字")

##=============图件的编辑操作===================
   @pyqtSlot()    ##放大
   def on_actZoomIn_triggered(self):
      items=self.scene.selectedItems()    # QGraphicsItem的列表
      cnt=len(items)  #选中的图形项的个数
      if cnt==1:  #只有一个图形项
         item=items[0]
         item.setScale(0.1+item.scale())
      else:
         self.view.scale(1.1,1.1)

   @pyqtSlot()    ##缩小
   def on_actZoomOut_triggered(self):
      items=self.scene.selectedItems()    # QGraphicsItem的列表
      cnt=len(items)    #选中的图形项的个数
      if cnt==1:        #只有一个图形项
         item=items[0]
         item.setScale(item.scale()-0.1)
      else:
         self.view.scale(0.9,0.9)   
      
   @pyqtSlot()    ##"恢复"取消所有缩放和旋转变换
   def on_actRestore_triggered(self):
      items=self.scene.selectedItems()    # QGraphicsItem的列表
      cnt=len(items)
      if cnt==1:  #单个图形项
         item=items[0]
         item.setScale(1)        #缩放还原
         item.setRotation(0)     #旋转还原
##         item.resetTransform()   #不起作用,BUG, PyQt 5.12
      else:
         self.view.resetTransform()
      
   @pyqtSlot()    ##左旋转
   def on_actRotateLeft_triggered(self):
      items=self.scene.selectedItems()    # QGraphicsItem的列表
      cnt=len(items)
      if cnt==1:
         item=items[0]
         item.setRotation(-30+item.rotation())
      else:
         self.view.rotate(-30)

   @pyqtSlot()    ##右旋转
   def on_actRotateRight_triggered(self):
      items=self.scene.selectedItems()    # QGraphicsItem的列表
      cnt=len(items)
      if cnt==1:
         item=items[0]
         item.setRotation(30+item.rotation())
      else:
         self.view.rotate(30)

   @pyqtSlot()    ##前置
   def on_actEdit_Front_triggered(self):
      items=self.scene.selectedItems()    # QGraphicsItem的列表
      cnt=len(items)
      if cnt>0 :
         item=items[0]
         self.__frontZ=1+self.__frontZ
         item.setZValue(self.__frontZ)
      
   @pyqtSlot()    ##后置
   def on_actEdit_Back_triggered(self):
      items=self.scene.selectedItems()    # QGraphicsItem的列表
      cnt=len(items)
      if cnt>0 :
         item=items[0]
         self.__backZ=self.__backZ-1
         item.setZValue(self.__backZ)

   @pyqtSlot()    ##组合
   def on_actGroup_triggered(self):
      items=self.scene.selectedItems()    # QGraphicsItem的列表
      cnt=len(items)  #选中的图形项个数
      if (cnt<=1):
        return 

      group =QGraphicsItemGroup() #创建组合
      self.scene.addItem(group)   #组合添加到场景中
      for i in range(cnt):
         item=items[i]
         item.setSelected(False)    #清除选择虚线框
         item.clearFocus()
         group.addToGroup(item)     #添加到组合

      group.setFlag(QGraphicsItem.ItemIsFocusable)
      group.setFlag(QGraphicsItem.ItemIsMovable)
      group.setFlag(QGraphicsItem.ItemIsSelectable)

      self.__frontZ=1+self.__frontZ
      group.setZValue(self.__frontZ)
      self.scene.clearSelection()
      group.setSelected(True)

   @pyqtSlot()    ##打散组合
   def on_actGroupBreak_triggered(self):
      items=self.scene.selectedItems()   
      cnt=len(items)
      if (cnt==1):  #假设选中的是QGraphicsItemGroup
         group=items[0]
         self.scene.destroyItemGroup(group)

   @pyqtSlot()    ##删除所有选中的绘图项
   def on_actEdit_Delete_triggered(self):
      items=self.scene.selectedItems()   
      cnt=len(items)
      for i in range(cnt):
         item=items[i]
         self.scene.removeItem(item)   #删除绘图项

        
##  =============自定义槽函数===============================        
   def  do_mouseMove(self,point):      ##鼠标移动
   ##鼠标移动事件,point是 GraphicsView的坐标,物理坐标
      self.__labViewCord.setText("View 坐标:%d,%d" %(point.x(),point.y()))
      pt=self.view.mapToScene(point)  #转换到Scene坐标
      self.__labSceneCord.setText("Scene 坐标:%.0f,%.0f"%(pt.x(),pt.y()))
   
   def  do_mouseClicked(self,point):   ##鼠标单击
      pt=self.view.mapToScene(point)  #转换到Scene坐标
      item=self.scene.itemAt(pt,self.view.transform())  #获取光标下的图形项
      if (item == None): 
         return
      pm=item.mapFromScene(pt)   #转换为绘图项的局部坐标
      self.__labItemCord.setText("Item 坐标:%.0f,%.0f"%(pm.x(),pm.y()))
      self.__labItemInfo.setText(str(item.data(self.__ItemDesc))
                    +", ItemId="+str(item.data(self.__ItemId)))

   def do_mouseDoubleClick(self,point):  ##鼠标双击
      pt=self.view.mapToScene(point)   #转换到Scene坐标,QPointF
      item=self.scene.itemAt(pt,self.view.transform())    #获取光标下的绘图项
      if (item == None): 
         return

      className=str(type(item))  #将类名称转换为字符串
   ##      print(className)
      
      if (className.find("QGraphicsRectItem") >=0):      #矩形框
         self.__setBrushColor(item)
      elif (className.find("QGraphicsEllipseItem")>=0):  #椭圆和圆都是 QGraphicsEllipseItem
         self.__setBrushColor(item)
      elif (className.find("QGraphicsPolygonItem")>=0):  #梯形和三角形
         self.__setBrushColor(item)
      elif (className.find("QGraphicsLineItem")>=0):     #直线,设置线条颜色
         pen=item.pen()
         color=item.pen().color()
         color=QColorDialog.getColor(color,self,"选择线条颜色")
         if color.isValid():
            pen.setColor(color)
            item.setPen(pen)
      elif (className.find("QGraphicsTextItem")>=0):     #文字,设置字体
         font=item.font()
         font,OK=QFontDialog.getFont(font)
         if OK:
            item.setFont(font)

   def do_keyPress(self,event):     ##按键操作
      items=self.scene.selectedItems() 
      cnt=len(items)
      if (cnt!=1):  
         return

      item=items[0]
      key=event.key()
      if (key==Qt.Key_Delete):       #删除
         self.scene.removeItem(item)
      elif (key==Qt.Key_Space):      #顺时针旋转90度
         item.setRotation(90+item.rotation())
      elif (key==Qt.Key_PageUp):     #放大
         item.setScale(0.1+item.scale())
      elif (key==Qt.Key_PageDown):  #缩小
         item.setScale(-0.1+item.scale())
      elif (key==Qt.Key_Left):      #左移
         item.setX(-1+item.x())
      elif (key==Qt.Key_Right):     #右移
         item.setX(1+item.x())
      elif (key==Qt.Key_Up):        #上移
         item.setY(-1+item.y())
      elif (key==Qt.Key_Down):      #下移
         item.setY(1+item.y())
Example #4
0
class QmyMainWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)  #调用父类构造函数,创建窗体

        self.__buildUI()  #构造界面
        self.__iniGraphicsSystem()  #初始化 graphics View系统

        self.view.mouseMove.connect(self.do_mouseMovePoint)  #鼠标移动
        self.view.mouseClicked.connect(self.do_mouseClicked)  #左键按下

##  ==============自定义功能函数============

    def __buildUI(self):  ##构造界面
        self.resize(600, 450)
        self.setWindowTitle("Demo8_5, View/Scene/Item关系和坐标变换")

        font = self.font()
        font.setPointSize(11)
        self.setFont(font)

        centralWidget = QWidget(self)  #中间工作区组件
        vLayoutMain = QVBoxLayout(centralWidget)  #垂直布局

        groupBox = QGroupBox(centralWidget)  #显示两个Label的groupBox
        vLayoutGroup = QVBoxLayout(groupBox)
        self.__labViewSize = QLabel(groupBox)
        self.__labViewSize.setText("view坐标,左上角(0,0),宽度=,长度=")

        vLayoutGroup.addWidget(self.__labViewSize)
        self.__labSceneRect = QLabel(groupBox)
        self.__labSceneRect.setText("view.sceneRect=()")
        vLayoutGroup.addWidget(self.__labSceneRect)

        vLayoutMain.addWidget(groupBox)  #主布局添加groupBox

        self.view = QmyGraphicsView(centralWidget)  #绘图视图
        self.view.setCursor(Qt.CrossCursor)
        self.view.setMouseTracking(True)
        ##      self.view.setDragMode(QGraphicsView.RubberBandDrag)
        vLayoutMain.addWidget(self.view)  #添加到主布局

        self.setCentralWidget(centralWidget)  #设置工作区中间组件

        statusBar = QStatusBar(self)  #状态栏
        self.setStatusBar(statusBar)

        self.__labViewCord = QLabel("View 坐标:")
        self.__labViewCord.setMinimumWidth(150)
        statusBar.addWidget(self.__labViewCord)

        self.__labSceneCord = QLabel("Scene 坐标:")
        self.__labSceneCord.setMinimumWidth(150)
        statusBar.addWidget(self.__labSceneCord)

        self.__labItemCord = QLabel("Item 坐标:")
        self.__labItemCord.setMinimumWidth(150)
        statusBar.addWidget(self.__labItemCord)

    def __iniGraphicsSystem(self):  ##初始化 graphics View系统
        rect = QRectF(-200, -100, 400, 200)
        self.scene = QGraphicsScene(rect)  #scene逻辑坐标系定义
        self.view.setScene(self.scene)

        ## 画一个矩形框,大小等于scene
        item = QGraphicsRectItem(rect)  #矩形框正好等于scene的大小
        item.setFlag(QGraphicsItem.ItemIsSelectable)  #可选,
        item.setFlag(QGraphicsItem.ItemIsFocusable)  #可以有焦点
        pen = QPen()
        pen.setWidth(2)
        item.setPen(pen)
        self.scene.addItem(item)

        ##一个位于scene中心的椭圆,测试局部坐标
        #矩形框内创建椭圆,绘图项的局部坐标,左上角(-100,-50),宽200,高100
        item2 = QGraphicsEllipseItem(-100, -50, 200, 100)
        item2.setPos(0, 0)
        item2.setBrush(QBrush(Qt.blue))
        item2.setFlag(QGraphicsItem.ItemIsSelectable)  #可选,
        item2.setFlag(QGraphicsItem.ItemIsFocusable)  #可以有焦点
        item2.setFlag(QGraphicsItem.ItemIsMovable)  #可移动

        self.scene.addItem(item2)

        ##一个圆,中心位于scene的边缘
        item3 = QGraphicsEllipseItem(-50, -50, 100, 100)  #矩形框内创建椭圆,绘图项的局部坐标
        item3.setPos(rect.right(), rect.bottom())
        item3.setBrush(QBrush(Qt.red))
        item3.setFlag(QGraphicsItem.ItemIsSelectable)  #可选,
        item3.setFlag(QGraphicsItem.ItemIsFocusable)  #可以有焦点
        item3.setFlag(QGraphicsItem.ItemIsMovable)  #可移动
        self.scene.addItem(item3)

        self.scene.clearSelection()

##==============event 处理函数=======================

    def resizeEvent(self, event):
        self.__labViewSize.setText('view坐标,左上角(0,0),宽度=%d,高度=%d' %
                                   (self.view.width(), self.view.height()))

        rectF = self.view.sceneRect()  #Scene的矩形区,QRectF
        self.__labSceneRect.setText(
            'view.sceneRect=(%.0f,%.0f,%.0f,%.0f)' %
            (rectF.left(), rectF.top(), rectF.width(), rectF.height()))

##  ==========由connectSlotsByName() 自动连接的槽函数==================

##  =============自定义槽函数===============================

    def do_mouseMovePoint(self, point):
        ##鼠标移动事件,point是 GraphicsView的坐标,物理坐标
        self.__labViewCord.setText("View坐标:%d,%d" % (point.x(), point.y()))
        pt = self.view.mapToScene(point)  #转换到Scene坐标
        self.__labSceneCord.setText("Scene坐标:%.0f,%.0f" % (pt.x(), pt.y()))

    def do_mouseClicked(self, point):
        pt = self.view.mapToScene(point)  #转换到Scene坐标
        item = None
        item = self.scene.itemAt(pt, self.view.transform())  #获取光标下的绘图项
        if (item != None):  #有绘图项
            pm = item.mapFromScene(pt)  #转换为绘图项的局部坐标
            self.__labItemCord.setText("Item坐标:%.0f,%.0f" % (pm.x(), pm.y()))