2015-10-14 4 views
0

В Qt я пытаюсь выделить элемент, когда я его нажимаю, а затем нарисую линию от ее конца до текущей позиции курсора. Я могу либо выделить его, либо нарисовать линию, но не обе. Вот мои классы:overriding paint() и mouseEvents() QGraphicsItem

// ucPin.h 
#pragma once 
#include "stdafx.h" 

class ucPin : public QGraphicsLineItem{ 
    qreal x1, y1, x2, y2; 
    bool isClicked; 
    QGraphicsLineItem * li; 
public : 

    ucPin (qreal x1, qreal y1, qreal x2, qreal y2, QGraphicsItem *parent = 0); 

    void paint (QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget); 
    void mousePressEvent (QGraphicsSceneMouseEvent * event); 
    void mouseReleaseEvent (QGraphicsSceneMouseEvent *event); 
    void mouseMoveEvent  (QGraphicsSceneMouseEvent *event); 

}; 

// ucPin.cpp 
    #include "ucPin.h" 

ucPin::ucPin (qreal x1, qreal y1, qreal x2, qreal y2, QGraphicsItem *parent) : 
     QGraphicsLineItem(x1, y1, x2, y2, parent){ 
     this->x1 = x1; this->y1 = y1; this->x2 = x2; this->y2 = y2; 
     this->setFlags(QGraphicsItem::ItemIsFocusable 
       | QGraphicsItem::ItemIsSelectable); 

     isClicked = false; 
     li = NULL; 
    } 

void ucPin::paint (QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget) 
{ 

    QStyleOptionGraphicsItem newOption (*option); 
    newOption.state =QStyle::State_None; 
    QGraphicsLineItem::paint(painter, &newOption, widget); 

    //painter-> setRenderHint(QPainter::Antialiasing); 


    if (option->state & QStyle::State_Selected) { 
     QPen outline; 
     outline.setColor(Qt::green); 
     outline.setWidth(6); 
     setPen(outline); 
    } 
    else{ 
     QPen outline; outline.setWidth(3); 
     setPen(outline); 
    } 
} 

void ucPin::mousePressEvent(QGraphicsSceneMouseEvent* event) { 
    /*QPointF pos = event->pos(); 

    QGraphicsLineItem * li = new QGraphicsLineItem(0,0, pos.x(), pos.y(), this);*/ 
    isClicked = true; 
} 

void ucPin::mouseReleaseEvent(QGraphicsSceneMouseEvent* event) { 
    isClicked = false; 
} 

void ucPin::mouseMoveEvent(QGraphicsSceneMouseEvent* event) { 
    if(NULL != li) { delete li; li = NULL;} 

    li = new QGraphicsLineItem(0,0, event->pos().x(), event->pos().y(), this); 

} 

Я думаю, при реализации переопределение MouseEvent, событие краски для выбранного состояния не дозвонились? Как можно обойти это?

+0

Я уверен, вы увидите, что вы хотите, если вы замените код в 'ucPin :: mouseMoveEvent' на' this-> setLine (0, 0, event-> pos(). X(), event-> pos () .y()) '. Почему вы создаете эту вещь 'li' в любом случае, если вы наследуете' QGraphicsLineItem'? – Rostislav

+0

Я хотел бы увидеть объект ucPin, выделенный. Вы, как вы указали, очень важны QGraphicsLine. Затем я хочу сделать еще одну строку и присоединиться к ней с оригиналом. Следовательно, li .. –

+0

Хорошо, имеет смысл. Посмотрите, помогает ли мой ответ. – Rostislav

ответ

0

Чтобы запросить перерисовку вашего QGraphicsItem, вам необходимо позвонить по номеру update() всякий раз, когда внешний вид меняется. setSelected вызывается в QGraphicsItem :: mousePressEvent, поэтому вам необходимо разложить его на базовый класс, вызвав QGraphicsLineItem::mousePressEvent(event) в ваш override mousePressEvent. То же самое касается mouseReleaseEvent. Или вы можете справиться с состоянием выбора самостоятельно, но не должны, если для этого нет веской причины. Кроме того, я думаю, что имеет смысл установить свои ручки перед вызовом QGraphicsLineItem::paint(...).

Кроме того, при каждом перемещении мыши нецелесообразно выделять новый li - просто выделите его один раз и используйте setLine, чтобы установить новые координаты.

+0

спасибо за ответ. Распределение является временным решением, пока я не пойму, как работает шаблон. В примере с размещенным кодом элемент управления никогда не вводит значение if (option-> state & QStyle :: State_Selected) в методе paint(), а не событие, вызывая update(). Это была моя первоначальная проблема, и почему я задал этот вопрос в первую очередь. –

+0

@MihaiGALOS А, ок. Чтобы выбранное состояние было настроено, вам необходимо распространить события кликов на базовый класс. См. Мой обновленный ответ. – Rostislav

+0

безупречный! Спасибо! –

Смежные вопросы