简体   繁体   中英

QT5 QgraphicsScene: how to draw on th forground pixel by pixel

I am using PyQt5. I am making a program of robots moving in a maze. For that, I use QGraphicsScene. I add objects like QRect to represent robots. The background is set via SetBackgroundBrush and loaded from a png image (black represents unpassable terrain): 这是它的样子

def update_background(self):
    qim = QImage(self.model.map.shape[1],self.model.map.shape[0], QImage.Format_RGB32)
    for x in range(0, self.model.map.shape[1]):
        for y in range(0, self.model.map.shape[0]):
            qim.setPixel(x ,y, qRgb(self.model.map[y,x],self.model.map[y,x],self.model.map[y,x]))
    pix = QPixmap(qim)
    self.scene.setBackgroundBrush(QBrush(pix))

What I want to do now is to visualize the work of a pathfinding algorithm (I use A* for now). Like a red line that connects the robot with its destination bending over obstacles. This line is stored as a list of (X,Y) coords. I wanted to iterate over the list and paint pixel by pixel on the scene. However I don't know how to do that - there is no "drawPixel" method. Of course, I can add a hundred of small rectangles of 1x1 size. However I will have to redraw them if the route changes.

I thought about creating an image with paths and placing it in the FOREground and then adding. However I cannot make a transparent foreground. It was not a problem with background (because it is in the back). I considered using theis function: http://doc.qt.io/qt-5/qpixmap.html#setAlphaChannel

But it is deprecated. It refers to QPainter. I don't know what QPainter is and I am not sure I am heading in the right direction at all.

Please give advice!

So, the question is what is the correct and efficient way to draw routes built by robots?

RobotPathItem(QGraphicsItem):
def __init__(self, path):
    super().__init__()
    qpath = []
    for xy in path:
        qpath.append(QPoint(xy[0],xy[1]))
    self.path = QPolygon(qpath)
    if path:
        print(path[0])

def paint(self, painter, option, qwidget = None):
    painter.drawPoints(self.path)
def boundingRect(self):
    return QRectF(0,0,520,520)

There's no drawPixel, but QPainter has a drawPoint or drawPoints (which would be a lot more efficient in this case, I think). You'll need to create a custom graphics item that contains your list of points and iterates through your list of QPointF values and draws them. When you add points to the list, be sure to recalculate the bounding rectangle. For example, if you had a RobotPathItem (derived from QGraphicsItem), your paint method might look something like:

RobotPathItem::paint (QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    QPen pen;
    // ... set up your pen color, etc., here
    painter->setPen (pen);
    painter->drawPoints (points, points.count ());
}

This is assuming that "points" is a QList or QVector of QPointF.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM