2017-02-03 5 views
0

Я использую PyQt5. Я делаю программу роботов, движущихся в лабиринте. Для этого я использую QGraphicsScene. Я добавляю объекты, такие как QRect, для представления роботов. Фон устанавливаются через SetBackgroundBrush и загружается из PNG изображения (черный представляет непроходимую местность): this is how it looksQT5 QgraphicsScene: как рисовать на ядре пиксель за пикселем

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)) 

То, что я хочу сделать сейчас, чтобы визуализировать работу алгоритма поиска пути (я использую * сейчас). Как красная линия, которая соединяет робота с целью его изгибания над препятствиями. Эта строка сохраняется как список (X, Y) коордов. Я хотел перебрать список и нарисовать пиксель на месте. Однако я не знаю, как это сделать - метода «drawPixel» нет. Конечно, я могу добавить сто маленьких прямоугольников размером 1x1. Однако мне придется перерисовать их, если маршрут изменится.

Я думал о создании изображения с путями и размещении его в FOREground, а затем добавлении. Однако я не могу сделать прозрачный передний план. Это не проблема с фоном (потому что он находится в задней части). Я рассмотрел использование функции theis: http://doc.qt.io/qt-5/qpixmap.html#setAlphaChannel

Но это устарело. Это относится к QPainter. Я не знаю, что такое QPainter, и я не уверен, что я направляюсь в правильном направлении.

Прошу совета!

Итак, вопрос в том, что является правильным и эффективным способом рисования маршрутов, построенных роботами?

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) 

ответ

2

Там нет drawPixel, но QPainter имеет drawPoint или drawPoints (что было бы гораздо более эффективным в этом случае, я думаю). Вам нужно будет создать пользовательский графический элемент, содержащий ваш список точек, и итерации через список значений QPointF и их рисование. Когда вы добавляете точки в список, обязательно пересчитайте ограничивающий прямоугольник. Например, если вы имели RobotPathItem (производную от QGraphicsItem), ваш метод краски может выглядеть примерно так:

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()); 
} 

Это предполагает, что «точка» является QList или QVector из QPointF.

+0

Это работает, но не полностью: Мне нужно обновить путь, поэтому я попробовал два способа: 1) каждый шаг, удалить старый путь и нарисовать новый. Это не работает и создает ошибку «не удается удалить 0-элемент», а старые пути не удаляются. Сцена начинает содержать все больше и больше объектов, они «сжимаются». 2) Я создаю один элемент, беру указатель на него, а затем изменяю то, что содержит этот указатель, создавая новый путь и помещая его туда. Это просто не приводит к перерисовке, путь остается таким же, как и в начале. – user2980475

+0

При дальнейшем рассмотрении выясняется, что мой QGraphicItem удаляет себя. Я не знаю, что случилось. Здесь я сформулировал новый вопрос (это ясно): http://stackoverflow.com/questions/42040974/custom-qgraphicsitem-deletes-itself – user2980475