pyside6使用问题记录(一)
近期在做的任务要把交通路网结构用PySide6可视化,并添加一些选择车道,拖拽车辆之类的交互操作。以下是在应用过程中出现的一些问题和解决方案。
问题1:qgraphicsview画polyline
由于希望界面上的部件都可以交互(点击,拖拽),因此我尝试在QGrahicsView
类里画,但发现QGraphicsScene
没有可直接调用的画polyline的函数,可行的方法是先画出QPainterPath,再用QGraphicsPath。如下面的程序,drawPolyline函数可输入2D
points, color, width,画出这些点的折线段。
1 |
|
问题2:画出来的polyline不够平滑,有锯齿
用上述方式画出的图如下图左图所示:斜线会有锯齿,只有完全水平或竖直或45度的线才是粗细均匀的。

为了平滑线段,可以给QGraphicsview
设置渲染的参数setRenderHint
为antialiasing(抗锯齿)。在__init__
函数里加入下面一行:
1 |
|
得到的结果如上面右图所示,可以看到没有锯齿了。
问题3:拖拽时view无法超过scene的大小
设置滚轮放大缩小功能需要重写wheelEvent函数,如下: 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28def wheelEvent(self, event: QtGui.QWheelEvent) -> None:
if len(self.scene().items()) == 0:
return
curPoint = event.position()
scenePos = self.mapToScene(QPoint(curPoint.x(), curPoint.y()))
viewWidth = self.viewport().width()
viewHeight = self.viewport().height()
hScale = curPoint.x() / viewWidth
vScale = curPoint.y() / viewHeight
wheelDeltaValue = event.angleDelta().y()
self.scaleFactor = self.transform().m11()
if (self.scaleFactor < 0.05 and wheelDeltaValue<0) or (self.scaleFactor>50 and wheelDeltaValue>0):
return
if wheelDeltaValue > 0:
self.scale(1.1, 1.1)
else:
self.scale(1.0/1.1, 1.0/1.1)
viewPoint = self.transform().map(scenePos)
self.horizontalScrollBar().setValue(int(viewPoint.x() - viewWidth * hScale ))
self.verticalScrollBar().setValue(int(viewPoint.y() - viewHeight * vScale ))
self.update()
设置鼠标拖拽功能只需要给QGraphicsView设置setDragMode,在window类初始化时加入
1 |
|
但在显示底图时由于图比较大,我并不想一开始显示全部,而只是显示一部分,如下图(1)。此时我的拖拽功能只在相比原始scene放大时才有用(在图(2)时可以拖拽)。当地图缩小后尽管还未显示地图全貌,但无法拖动(图(3)无法拖动)。

参考这个回答:https://stackoverflow.com/questions/55007339/allow-qgraphicsview-to-move-outside-scene
一个简单粗暴的解决方法是给scene设置足够大的初始大小。在我的例子中我将大小改为:
1 |
|
这样就可以在上图(3)仍然可以拖动。不过修改scene_map的大小后要注意原本点的位置的按照scene_map的大小改变。由于QGraphicsScene
默认是中心和QGraphicsView
对齐的,如scene_map大小设为(2000,2000),那么此时scene中心点的坐标(1000,1000)会显示在view的中心。