PyQt - 在小部件顶部显示小部件

PyQt - 在小部件顶部显示小部件

问题描述:

我正在制作一个显示区域地图的应用程序,并试图在其上绘制表示信息的节点。PyQt - 在小部件顶部显示小部件

我完成了所有工作,但是只是通过制作一个自定义小部件,然后在每次更改信息时一次又一次地打印所有内容。此外,我无法将节点“连接”到侦听器,因为它们只是原始小部件中的图像。

这使我想改革我的GUI,现在我试图让每个类都成为一个自定义小部件!但是有一个问题,我的MapNodes不再显示。

我搜索计算器,发现这是很有帮助的主题:(?) How to set absolute position of the widgets in qt

所以我必须给我的mapnodes父母,和父母=内容显示小部件

不管怎么说,这是我的扔在它,在这里粘贴相关的代码。提示哪里可能会出现可怕的错误:所有inits

app = QtGui.QApplication(list()) 
mutexbranch = Lock() 
mutexnode = Lock() 

def exec(): 
    return app.exec_() 

#Singleton Pattern: wanneer en object aan iets moet kunnen 
#     waar het inherent door de structuur niet aankon 
#     wordt dit via dit singleton opgelost 
class GuiInternalCommunication: 
    realmap = 0 


class MapView(QtGui.QWidget, listener.Listener): 
    def __init__(self, mapimagepath): 
     QtGui.QMainWindow.__init__(self) 
     listener.Listener.__init__(self) 

     self.map = Map(self, mapimagepath) 
     #self.setCentralWidget(self.map) 

     self.initUI() 


    def initUI(self): 
     self.setWindowTitle('Population mapping') 

     hbox = QtGui.QHBoxLayout() 
     hbox.addWidget(self.map) 

     self.setLayout(hbox) 

     resolution = QtGui.QDesktopWidget().screenGeometry() 
     self.setGeometry(20,20,550,800) 
     self.show() 



###################################################################### 

class Map(QtGui.QWidget): 
    def __init__(self, parent, mapimagepath): 
     QtGui.QWidget.__init__(self, parent) 

     #self.timer = QtCore.QBasicTimer() 

     #coordinaten hoeken NE en SW voor kaart in map graphics van SKO 
     self.realmap = RealMap( 
      mapimagepath, 
      (51.0442, 3.7268), 
      (51.0405, 3.7242), 
      550, 
      800) 
     GuiInternalCommunication.realmap = self.realmap 

     self.needsupdate = True 
     self.timelabel = 0 

     parent.setGeometry(0,0,self.realmap.width, self.realmap.height) 

     self.mapNodes = {} 
     self.mapBranches = {} 

    def paintEvent(self, event): 
     painter = QtGui.QPainter() 
     painter.begin(self) 
     rect = self.contentsRect() 

     #teken achtergrond 
     self.realmap.drawRealMap(painter) 

     #teken branches 
     mutexbranch.acquire() 
     try: 
      for branch, mapBranch in self.mapBranches.items(): 
       mapBranch.drawMapBranch(painter) 
     finally: 
      mutexbranch.release()   



###################################################################### 

class RealMap(QtGui.QWidget): 
    def __init__(self, path, coordRightTop, coordLeftBot, width, height, pixpermet = 2.6): 
     super(RealMap, self).__init__() 
     self.path = path 
     self.mapimage = QtGui.QImage(self.path) 
     self.coordLeftBot = coordLeftBot 
     self.coordRightTop = coordRightTop 

     self.width = width 
     self.height = height 

     self.realdim = self.calcRealDim() 

     self.pixpermet = pixpermet 

    def paintEvent(self, e): 
     painter = QtGui.QPainter() 
     painter.begin(self) 
     self.drawRealMap(self, painter) 
     painter.end() 

    def drawRealMap(self, painter): 
     painter.drawImage(0,0,self.mapimage) 


###################################################################### 

class MapNode(QtGui.QWidget): 
    dangertocolor = {"normal":"graphics//gradients//green.png", 
        "elevated":"graphics//gradients//orange.png", 
        "danger":"graphics//gradients//red.png"} 

    gradimage = {"normal":QtGui.QImage(dangertocolor["normal"]), 
        "elevated":QtGui.QImage(dangertocolor["elevated"]), 
        "danger":QtGui.QImage(dangertocolor["danger"])} 
    btimage = QtGui.QImage("graphics//BT-icon.png") 

    def __init__(self, scanner, x, y, danger = 0, parent = None): 
     # MapNode erft over van QWidget 
     super(MapNode, self).__init__() 
     QtGui.QWidget.__init__(self, parent) 

     self.scanner = scanner 
     self.x = x 
     self.y = y 
     self.danger = 'normal' 
     self.calcDanger(danger) 

     self.grads = {} 
     self.grad = QtGui.QImage(MapNode.dangertocolor[self.danger]) 


    def paintEvent(self, e): 
     painter = QtGui.QPainter() 
     painter.begin(self) 
     self.drawMapNode(painter) 
     painter.end() 

    def drawMapNode(self, painter): 
     realmap = GuiInternalCommunication.realmap 
     radiusm = self.scanner.range 
     radiusp = radiusm*realmap.pixpermet 
     factor = radiusp/200  # basis grootte gradiënten is 200 pixels. 

     grad = MapNode.gradimage[self.danger] 
     grad = grad.scaled(grad.size().width()*factor, grad.size().height()*factor) 

     painter.drawImage(self.x-100*factor,self.y-100*factor, grad) 
     painter.drawImage(self.x-10, self.y-10,MapNode.btimage) 
     painter.drawText(self.x-15, self.y+20, str(self.scanner.sensorid) + '-' + str(self.scanner.name)) 


###################################################################### 

class MapBranch: 
    branchpens = {"normal": QtGui.QPen(QtCore.Qt.green, 3, QtCore.Qt.DashLine), 
       "elevated": QtGui.QPen(QtGui.QColor(255, 51, 0), 3, QtCore.Qt.DashLine), #mandarine orange hex is 255-165-0 
       "danger": QtGui.QPen(QtCore.Qt.red, 3, QtCore.Qt.DashLine)} 

    def __init__(self, branch, mapnode1, mapnode2, danger = 0): 
     self.mapnode1 = mapnode1 
     self.mapnode2 = mapnode2 
     self.branch = branch 
     self.danger = danger 

     self.calcDanger(danger) 

    def drawMapBranch(self, painter): 
     painter.setPen(MapBranch.branchpens[self.danger]) 
     painter.drawLine(self.mapnode1.x, 
         self.mapnode1.y, 
         self.mapnode2.x, 
         self.mapnode2.y) 

编辑 - 我忘了添加添加节点的代码。所以后一个事件涉及的节点需要被创建,这个方法火灾创建节点:

def addNode(self, scanner): 
    mutexnode.acquire() 
    try: 
     coord = self.realmap.convertLatLon2Pix((scanner.latitude, scanner.longitude)) 
     self.mapNodes[scanner.sensorid] = MapNode(scanner, coord[0], coord[1], parent = self) 
     self.mapNodes[scanner.sensorid].move(coord[0],coord[1]) 
     #self.mapNodes[scanner.sensorid].show() 
    finally: 
     mutexnode.release() 

我会建议你使用QGraphicsScene和的QGraphicsItem类地图,而不是正常的QWidget类,因为它们是恰好由用于显示大量的图形项目的目的:

从文档:

的QGraphicsScene类提供了一个表面,用于管理大量的2D图形项目。

该类用作QGraphicsItems的容器。它与QGraphicsView一起用于在2D表面上可视化图形项目,例如线条,矩形,文本甚至自定义项目。 QGraphicsScene是Graphics View Framework的一部分。

QGraphicsScene还提供了一些功能,可以让您高效地确定项目的位置以及确定场景中任意区域内可见的项目。使用QGraphicsView小部件,您可以可视化整个场景,也可以放大并仅查看场景的一部分。

您还可以在场景中嵌入派生自QWidget的小部件,这应该允许您实际显示任何类型的信息。作为奖励,您将获得分层,快速转换和即时使用的鼠标交互处理,这对于实现交互式地图应该非常有用。

+1

上述链接已过期 – 2017-07-27 14:46:55

+0

感谢举报此信息,我修复了这些问题! – ThePhysicist 2017-08-03 12:26:01