PyQt -显示小部件之上的小部件



我正在制作一个显示一个区域地图的应用程序,我正在尝试在它上面绘制节点,这些节点可以代表信息。

我让这一切都工作,但这样做只是通过制作一个自定义的小部件,我显示和打印一切一次又一次每次信息改变。此外,我无法将节点"连接"到侦听器,因为它们只是原始小部件中的图像。

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

我搜索了stackoverflow,发现了这个有用的线程:如何在qt

中设置小部件的绝对位置

所以我必须给我的mapnodes一个parent, parent =正在显示的小部件(?)

无论如何,这是我的尝试,将相关代码粘贴在这里。提示可能出现严重错误的地方:所有的init
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 http://doc.qt.io/qt-5/qgraphicsscene.html
  • QGraphicsItem: http://doc.qt.io/qt-5/qgraphicsitem-members.html

来自文档:

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

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

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

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

相关内容

  • 没有找到相关文章

最新更新