crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Перерисовка QGraphicsScene.
AlexandrosLiberalis
  опции профиля:
сообщение 17.8.2014, 11:24
Сообщение #1


Новичок


Группа: Новичок
Сообщений: 8
Регистрация: 21.7.2014
Пользователь №: 4193

Спасибо сказали: 0 раз(а)




Репутация:   0  


Всем привет!

Новичок.
Я делаю программу для рисования графов.
Для рисования на QGraphicsScene есть два класса: Node и Edge.

Эти классы рисуют вершины и дуги соответственно.
Объект класса Node имеет флаг ItemIsMovable.
При добавлении объекта Edge пользователь задаёт начальный и конечный объекты Node, которые в свою очередь дают координаты для рисования линии стрелки объекта Edge.
После перемещения вершин, QGraphicsScene необходимо перерисовать, и пока я для этого использую кнопку на диалоге, в которой пишу код для рисования и в конце scene->update();

Как сделать перерисовку при перемещении вершины или её "отпускании"?

Класс Node уже содержит метод mouseReleaseEvent() и, в моём понимании, его необходимо соединить с каким то слотом в главном диалоге, который в свою очередь всё перерисует.
Подскажите пожалуйста, как это сделать.
проект прилагаю.
Прикрепленные файлы
Прикрепленный файл  FF.ZIP ( 13.12 килобайт ) Кол-во скачиваний: 208
 
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Trisch
  опции профиля:
сообщение 17.8.2014, 11:41
Сообщение #2


Активный участник
***

Группа: Участник
Сообщений: 379
Регистрация: 30.1.2012
Из: Запорожье
Пользователь №: 3169

Спасибо сказали: 24 раз(а)




Репутация:   0  


в методе mouseReleaseEvent() вы посылаете сигнал, который соединен с слотом, который в свою очередь все обновляет.

дополнительная инфа по сигналам и слотам

Сообщение отредактировал Trisch - 17.8.2014, 11:43
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AlexandrosLiberalis
  опции профиля:
сообщение 17.8.2014, 13:09
Сообщение #3


Новичок


Группа: Новичок
Сообщений: 8
Регистрация: 21.7.2014
Пользователь №: 4193

Спасибо сказали: 0 раз(а)




Репутация:   0  


В объявлении Node обозначил как сигнал

signals:
void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);

В объявлении главного диалога объявил слот

public slots:
void MySlot();

В реализации главного диалога написал:

connect(node, SIGNAL(mouseReleaseEvent(QGraphicsSceneMouseEvent *event)), this, SLOT(MySlot()));

Ещё вычитал, что в объявление класса sender'а нужно добавить Q_OBJECT

Не работает.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Trisch
  опции профиля:
сообщение 17.8.2014, 15:23
Сообщение #4


Активный участник
***

Группа: Участник
Сообщений: 379
Регистрация: 30.1.2012
Из: Запорожье
Пользователь №: 3169

Спасибо сказали: 24 раз(а)




Репутация:   0  


Нельзя void mouseReleaseEvent(QGraphicsSceneMouseEvent *event), сделать сигналом, так как это виртуальная функция.

надо определить новый сигнал и его уже послать из функции void mouseReleaseEvent(QGraphicsSceneMouseEvent *event);

К примеру:

...
signals:
    void MySignal();
...

void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
...
    emit MySignal();
...
}
...
connect(node, SIGNAL(MySignal()), this, SLOT(MySlot()));
...


Сообщение отредактировал Trisch - 17.8.2014, 15:24
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 17.8.2014, 15:24
Сообщение #5


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Нужно менять своиства ребер соединеных с данной вершиной, а лучше всего сделать так:
1. В ребро добавить номера узлов которые оно соединяет(или указатели на эти узлы)
2. В методе paint ребра, спрашивать координаты концов у соответствующих узлов и рисовать их в этой точке.
Тогда никакие сигналы.слоты не понадобятся, достаточно будет update, который уж есть в обработчике мыши.

    addnewedgeproto->exec();
    if (addnewedgeproto->exec() == QDialog::Accepted){

Тут диалог вызывается два раза. Первый вызов можно безболезненно убрать.

Вы так и не переделали работу с памятью. Assert при выходе.

Используйте double вместо float. Экономить вам не зачем.

Чтобы проще рисовать стрелки, рисуйте в системе координат конца линии, используйте методы QPainter::translate, QPainter::rotate.

(edge + i) полностью эквивалентно edge[i] но последнее короче и проще читается.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AlexandrosLiberalis
  опции профиля:
сообщение 17.8.2014, 17:34
Сообщение #6


Новичок


Группа: Новичок
Сообщений: 8
Регистрация: 21.7.2014
Пользователь №: 4193

Спасибо сказали: 0 раз(а)




Репутация:   0  


Trisch,
Что то всё равно не получается, говорит " cannot convert parameter from Node to const QObject ", показывая на строчку

connect(node, SIGNAL(mouseReleaseEvent(QGraphicsSceneMouseEvent *event)), this, SLOT(MySlot()));


Цитата(lanz @ 17.8.2014, 16:24) *
Нужно менять своиства ребер соединеных с данной вершиной, а лучше всего сделать так:
1. В ребро добавить номера узлов которые оно соединяет(или указатели на эти узлы)
2. В методе paint ребра, спрашивать координаты концов у соответствующих узлов и рисовать их в этой точке.
Тогда никакие сигналы.слоты не понадобятся, достаточно будет update, который уж есть в обработчике мыши.


Что то на это моего воображения не хватает. Хотя вроде я то же самое и делаю. В Edge есть переменные xstart, ystart, xend, yend, которым я присваиваю координаты соответствующих Node, делаю это в диалоге. А вот как запрашивать....



За остальные замечания спасибо, про память - это мне ещё предстоит одолеть, а пока программа периодически падает, перезапускаю проект и работаю снова((
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Trisch
  опции профиля:
сообщение 17.8.2014, 20:38
Сообщение #7


Активный участник
***

Группа: Участник
Сообщений: 379
Регистрация: 30.1.2012
Из: Запорожье
Пользователь №: 3169

Спасибо сказали: 24 раз(а)




Репутация:   0  


Цитата(AlexandrosLiberalis @ 17.8.2014, 17:34) *
Trisch,
Что то всё равно не получается, говорит " cannot convert parameter from Node to const QObject ", показывая на строчку


В класс Node надо добавить макрос Q_OBJECT.

По ссылке, что я дал выше, об этом написано.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
AlexandrosLiberalis
  опции профиля:
сообщение 17.8.2014, 20:41
Сообщение #8


Новичок


Группа: Новичок
Сообщений: 8
Регистрация: 21.7.2014
Пользователь №: 4193

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Trisch @ 17.8.2014, 21:38) *
Цитата(AlexandrosLiberalis @ 17.8.2014, 17:34) *
Trisch,
Что то всё равно не получается, говорит " cannot convert parameter from Node to const QObject ", показывая на строчку


В класс Node надо добавить макрос Q_OBJECT.

По ссылке, что я дал выше, об этом написано.


и это я сделал
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
lanz
  опции профиля:
сообщение 18.8.2014, 0:06
Сообщение #9


Старейший участник
****

Группа: Участник
Сообщений: 690
Регистрация: 28.12.2012
Пользователь №: 3660

Спасибо сказали: 113 раз(а)




Репутация:   8  


Цитата
и это я сделал

Надо наследовать тогда от QGraphicsObject
http://qt-project.org/doc/qt-4.8/qgraphicsobject.html

Цитата(AlexandrosLiberalis @ 17.8.2014, 18:34) *
Что то на это моего воображения не хватает. Хотя вроде я то же самое и делаю. В Edge есть переменные xstart, ystart, xend, yend, которым я присваиваю координаты соответствующих Node, делаю это в диалоге. А вот как запрашивать....

На самом деле тут все просто. У вас проблема в том что вы храните одни и те же данные в двух местах, и их приходится синхронизировать.
То что вам примерно надо:
class Node : ...
{
  ...
  QVector<Edge*> adjacentEdges;
  int x;
  int y;
}

class Edge : ...
{
  ...
  Node * source;
  Node * target;

  ...
  void paint(...) {
    int startX = source->x;
    int startY = source->y;

    int targetX = target->x;
    int targetY = target->y;
    ...
  }
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
afrit
  опции профиля:
сообщение 23.8.2014, 20:48
Сообщение #10


Новичок


Группа: Новичок
Сообщений: 3
Регистрация: 12.2.2014
Пользователь №: 4053

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(Trisch @ 17.8.2014, 12:41) *
в методе mouseReleaseEvent() вы посылаете сигнал, который соединен с слотом, который в свою очередь все обновляет.
дополнительная инфа по сигналам и слотам


Беда в том, что Node и Edge наследуются от QGraphicsItem, который в свою очередь о QObject ничего не знает, сигналы/слоты работать не будут.
Как вариант, используйте QGraphicsObject или самостоятельно сделайте двойное наследование.
А вообще, если я правильно понял задачу, посмотрите на http://qt-project.org/forums/viewthread/33448
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 28.3.2024, 14:33