python - PyQt - displaying widget on top of widget -
i'm making application shows map of area , i'm trying draw nodes on top of can represent information.
i made work, did making 1 custom widget showed , printing again , again everytime information changed. couldn't 'connect' nodes listeners, because images in original widget.
this made me want reform gui , i'm trying make every class custom widget! there's problem, mapnodes aren't showing anymore.
i searched stackoverflow , found helpful thread: how set absolute position of widgets in qt
so have give mapnodes parent, , parent = widget being shown (?)
anyway, here throw @ it, pasting relevant code here. hint @ stuff might go horrible wrong: 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: 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 on 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 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 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)
edit - forgot add code adds nodes. after event comes in node needs created, method fires creating node:
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()
i recommend use qgraphicsscene , qgraphicsitem classes map instead of normal qwidget classes, since made purpose of displaying large number of graphical items:
- qgraphicsscene http://doc.qt.io/qt-5/qgraphicsscene.html
- qgraphicsitem: http://doc.qt.io/qt-5/qgraphicsitem-members.html
from documentation:
the qgraphicsscene class provides surface managing large number of 2d graphical items.
the class serves container qgraphicsitems. used qgraphicsview visualizing graphical items, such lines, rectangles, text, or custom items, on 2d surface. qgraphicsscene part of graphics view framework.
qgraphicsscene provides functionality lets efficiently determine both location of items, , determining items visible within arbitrary area on scene. qgraphicsview widget, can either visualize whole scene, or zoom in , view parts of scene.
you can embed widgets derived qwidget in scene, should allow display practically kind of information. bonus, layering, fast transformations , ready-to-use handling of mouse interactions, should quite useful realizing interactive map.
Comments
Post a Comment