From e0132fa617e8a5dfb19b134d5d3b1aed1fa7ded3 Mon Sep 17 00:00:00 2001 From: leo Date: Sat, 12 Feb 2022 23:50:41 +0100 Subject: [PATCH] =?UTF-8?q?Remplac=C3=A9=20pygame=20par=20QT,=20j'aime=20p?= =?UTF-8?q?as=20pygame?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Car.py | 12 ++++---- CarController.py | 11 +++----- Map.py | 35 ++++++++++------------- main.py | 72 ++++++++++++++++++++++-------------------------- mainLoop.py | 19 +++++++++++++ mainPainter.py | 39 ++++++++++++++++++++++++++ window.py | 59 +++++++++++++++++++++++++++++++++++++++ window.ui | 48 ++++++++++++++++++++++++++++++++ 8 files changed, 223 insertions(+), 72 deletions(-) create mode 100644 mainLoop.py create mode 100644 mainPainter.py create mode 100644 window.py create mode 100644 window.ui diff --git a/Car.py b/Car.py index b52ae23..e7c37aa 100644 --- a/Car.py +++ b/Car.py @@ -1,6 +1,7 @@ import sumolib -import pygame as pg import math +from PySide6.QtGui import QPainter +from PySide6.QtCore import QPointF class Car: def initPath(self): @@ -18,7 +19,7 @@ class Car: print(f"{self.id} : {startEdge.getID()} -> {nextEdge.getID()} via {laneId}") - def __init__(self,carID,route,parentMap,parentController,surface): + def __init__(self,carID,route,parentMap,parentController): self.id=carID self.map=parentMap self.controller=parentController @@ -49,10 +50,9 @@ class Car: self.a=10 self.b=20 - self.surf=surface - - def draw(self,col): - pg.draw.circle(self.surf,col,self.map.convertPos(self.pos),5) + def draw(self,painter): + pt = QPointF(*self.pos) + painter.drawEllipse(pt,3,3) def conduite(self,vmax,leader,dt): if(leader==None): diff --git a/CarController.py b/CarController.py index 4846cf3..cf7d86e 100644 --- a/CarController.py +++ b/CarController.py @@ -2,16 +2,14 @@ import sumolib from Car import Car class CarController: - def __init__(self,path,parentMap,surface): + def __init__(self,parentMap): self.map=parentMap - self.surf=surface self.cars=[] - self.fromPath(path) def fromPath(self,path): for vehicle in sumolib.xml.parse(path,"vehicle"): route=vehicle.route[0].edges.split() - self.cars.append(Car(vehicle.id,route,self.map,self,self.surf)) + self.cars.append(Car(vehicle.id,route,self.map,self)) def getCarsOnEdge(self,edgeID): # on devrai probablement utiliser une map ici (dict en python?) mais flemme res=[] @@ -25,7 +23,6 @@ class CarController: for car in self.cars: car.update(1.0/60) - def draw(self,screen): + def draw(self,painter): for car in self.cars: - car.draw((255,255,255)) - screen.blit(self.surf,(0,0)) + car.draw(painter) diff --git a/Map.py b/Map.py index e330e5c..f16c4d0 100644 --- a/Map.py +++ b/Map.py @@ -3,35 +3,27 @@ # mais si on se decide à utiliser notre propre format dans le futur ça facilitera la transition import sumolib -import pygame as pg +from PySide6.QtGui import QPainter, QPolygonF +from PySide6.QtCore import Qt, QPointF class Map: - def __init__(self,path,surface): - self.fromPath(path) - self.surf=surface + def __init__(self,path=None): + if path!=None: + self.fromPath(path) def fromPath(self,path): self.net = sumolib.net.readNet(path,withInternal=True,withConnections=True) - - def text(self,text,pos,font): - img = font.render(text,True,(255,255,255)) - self.surf.blit(img,pos) - def draw(self,screen,debug=False,font=None): + def draw(self, painter): for edge in self.net.getEdges(): - color=(255,255,255) + color=Qt.white if(edge.getFunction()=="internal"): - color=(255,0,0) + color=Qt.red + painter.setPen(color) for lane in edge.getLanes(): - pts=lane.getShape() - pts=map(self.convertPos,pts) - pg.draw.lines(self.surf,color,False,list(pts)) - - if(debug): - for node in self.net.getNodes(): - self.text(node.getID(),self.convertPos(node.getCoord()),font) - - screen.blit(self.surf,(0,0)) + pts=[QPointF(*p) for p in lane.getShape()] + poly = QPolygonF.fromList(pts) + painter.drawPolyline(poly) def getEdge(self,edgeID): return self.net.getEdge(edgeID) @@ -42,6 +34,9 @@ class Map: def getLane(self,laneID): return self.net.getLane(laneID) + def getBounds(self): + return self.net.getBBoxXY() + def convertPos(self,pos): bounds=self.net.getBoundary() bounds[0]-=200 diff --git a/main.py b/main.py index b934828..bd36055 100644 --- a/main.py +++ b/main.py @@ -6,47 +6,41 @@ if 'SUMO_HOME' in os.environ: else: print("please declare environment variable 'SUMO_HOME'") -import pygame as pg -from pygame.locals import * +from PySide6.QtCore import Qt, QTimer +from PySide6.QtWidgets import QApplication, QMainWindow +from PySide6.QtGui import QSurfaceFormat +from window import Ui_MainWindow -from Map import Map -from CarController import CarController +from mainLoop import mainLoop -pg.init() - -font = pg.font.SysFont(None, 20) - -screen = pg.display.set_mode((1280, 480), pg.SCALED) -pg.display.set_caption("Traffic") - -clk = pg.time.Clock() - -netSurf = pg.Surface(screen.get_size(),pg.SRCALPHA) -netSurf = netSurf.convert() -m = Map("test2.net.xml",netSurf) - -carSurf = pg.Surface(screen.get_size()) -carSurf.set_colorkey((0, 0, 0)) -carSurf = carSurf.convert() -cc = CarController("test5.rou.xml",m,carSurf) - -time.sleep(10) - -running = True -while running: - for event in pg.event.get(): - if event.type == pg.QUIT: - running = False - elif event.type == pg.KEYDOWN and event.key == pg.K_ESCAPE: - running = False - elif event.type == pg.KEYDOWN and event.key == pg.K_q: - running = False +class MainWindow(QMainWindow): + def __init__(self): + super(MainWindow, self).__init__() + self.ui = Ui_MainWindow() + self.ui.setupUi(self) - carSurf.fill((0,0,0)) - m.draw(screen,debug=False,font=font) - cc.update() - cc.draw(screen) - pg.display.flip() + self.mainLoop = mainLoop(self.ui.mainSurf) + + timer = QTimer(self) + timer.timeout.connect(self.mainLoop.update) + timer.start(1.0/60) + + def keyPressEvent(self, e): + if e.key() == Qt.Key_Escape or e.key() == Qt.Key_Q: + self.close() - clk.tick(60) +if __name__ == "__main__": + app = QApplication() + + format = QSurfaceFormat() + format.setDepthBufferSize(24) + format.setStencilBufferSize(8) + format.setVersion(3, 2) + format.setSamples(16) + format.setProfile(QSurfaceFormat.CoreProfile) + QSurfaceFormat.setDefaultFormat(format) + window = MainWindow() + window.show() + + sys.exit(app.exec()) diff --git a/mainLoop.py b/mainLoop.py new file mode 100644 index 0000000..c4c4a8f --- /dev/null +++ b/mainLoop.py @@ -0,0 +1,19 @@ +from Map import Map +from CarController import CarController + +class mainLoop(): + def __init__(self, painter): + self.painter = painter + + self.map = Map() + self.map.fromPath("test2.net.xml") + + self.controller = CarController(self.map) + self.controller.fromPath("test5.rou.xml") + + self.painter.addMap(self.map) + self.painter.addCarController(self.controller) + + def update(self): + self.controller.update() + self.painter.update() diff --git a/mainPainter.py b/mainPainter.py new file mode 100644 index 0000000..791c3ce --- /dev/null +++ b/mainPainter.py @@ -0,0 +1,39 @@ +from PySide6.QtOpenGLWidgets import QOpenGLWidget +from PySide6.QtCore import Qt +from PySide6.QtGui import QPainter, QFont, QColor, QTransform + +class mainPainter(QOpenGLWidget): + def __init__(self, parent=None): + super(mainPainter, self).__init__(parent) + self.map = None + self.carController = None + self.transform = QTransform() + + def addMap(self, netMap): + self.map = netMap + + def addCarController(self, cc): + self.carController = cc + + def generateTransform(self): + bounds = self.map.getBounds() + bounds[0] = list(map(lambda b: b-10,bounds[0])) + bounds[1] = list(map(lambda b: b+10, bounds[1])) + self.transform.reset() + tr = QTransform() + tr.translate(-bounds[0][0],-bounds[0][1]) + scale=min(self.width()/(bounds[1][0]-bounds[0][0]),self.height()/(bounds[1][1]-bounds[0][1])) + sc = QTransform() + sc.scale(scale,-scale) + self.transform = tr * sc * QTransform(1, 0, 0, 1, 0, self.height()) + + def resizeGL(self,w,h): + self.generateTransform() + + def paintEvent(self, e): + painter = QPainter(self) + painter.RenderHint(QPainter.Antialiasing) + painter.eraseRect(e.rect()); + painter.setTransform(self.transform) + self.map.draw(painter) + self.carController.draw(painter) diff --git a/window.py b/window.py new file mode 100644 index 0000000..2a2d6cc --- /dev/null +++ b/window.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- + +################################################################################ +## Form generated from reading UI file 'window.ui' +## +## Created by: Qt User Interface Compiler version 6.2.3 +## +## WARNING! All changes made in this file will be lost when recompiling UI file! +################################################################################ + +from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale, + QMetaObject, QObject, QPoint, QRect, + QSize, QTime, QUrl, Qt) +from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor, + QFont, QFontDatabase, QGradient, QIcon, + QImage, QKeySequence, QLinearGradient, QPainter, + QPalette, QPixmap, QRadialGradient, QTransform) +from PySide6.QtWidgets import (QApplication, QGridLayout, QHBoxLayout, QMainWindow, + QMenuBar, QSizePolicy, QStatusBar, QWidget) + +from mainPainter import mainPainter + +class Ui_MainWindow(object): + def setupUi(self, MainWindow): + if not MainWindow.objectName(): + MainWindow.setObjectName(u"MainWindow") + MainWindow.resize(800, 600) + self.centralwidget = QWidget(MainWindow) + self.centralwidget.setObjectName(u"centralwidget") + self.gridLayout = QGridLayout(self.centralwidget) + self.gridLayout.setObjectName(u"gridLayout") + self.horizontalLayout = QHBoxLayout() + self.horizontalLayout.setObjectName(u"horizontalLayout") + self.mainSurf = mainPainter(self.centralwidget) + self.mainSurf.setObjectName(u"mainSurf") + + self.horizontalLayout.addWidget(self.mainSurf) + + + self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1) + + MainWindow.setCentralWidget(self.centralwidget) + self.menubar = QMenuBar(MainWindow) + self.menubar.setObjectName(u"menubar") + self.menubar.setGeometry(QRect(0, 0, 800, 27)) + MainWindow.setMenuBar(self.menubar) + self.statusbar = QStatusBar(MainWindow) + self.statusbar.setObjectName(u"statusbar") + MainWindow.setStatusBar(self.statusbar) + + self.retranslateUi(MainWindow) + + QMetaObject.connectSlotsByName(MainWindow) + # setupUi + + def retranslateUi(self, MainWindow): + MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None)) + # retranslateUi + diff --git a/window.ui b/window.ui new file mode 100644 index 0000000..d2248e6 --- /dev/null +++ b/window.ui @@ -0,0 +1,48 @@ + + + MainWindow + + + + 0 + 0 + 800 + 600 + + + + MainWindow + + + + + + + + + + + + + + + + 0 + 0 + 800 + 27 + + + + + + + + mainPainter + QOpenGLWidget +
mainPainter
+
+
+ + +