Russian Qt Forum

Qt => 2D и 3D графика => Тема начата: troorl от Апрель 14, 2007, 04:06



Название: QGraphicsItem - как добраться до своего метода?
Отправлено: troorl от Апрель 14, 2007, 04:06
Наследую класс на основе QGraphicsItem. Определяю там свой метод. Дальше добавляю объект этого класса на сцену. Как я могу достучаться до своего метода?
QGraphicsScene::items().at(i) этого делать не хочет :(


Название: Re: QGraphicsItem - как добраться до своего метода?
Отправлено: vregess от Апрель 14, 2007, 10:13
Цитата: "troorl"
Наследую класс на основе QGraphicsItem. Определяю там свой метод. Дальше добавляю объект этого класса на сцену. Как я могу достучаться до своего метода?
QGraphicsScene::items().at(i) этого делать не хочет :(


мало информации.
Дела с QGraphicsItem не имел, но подозреваю, что надо:
Код:

// YourClass <--- ваш наследник от QGraphicsItem

static_cast<YourClass*>(QGraphicsScene::items().at(i))->yourMethod();



Название: QGraphicsItem - как добраться до своего метода?
Отправлено: QCasper от Апрель 14, 2007, 12:41
Или qgraphicsitem_cast чтоб уж наверняка :)


Название: QGraphicsItem - как добраться до своего метода?
Отправлено: troorl от Апрель 14, 2007, 15:16
О, спасибо, вроде помогло. Ещё бы на лету узнавать тип обьекта - было бы вообще замечательно :)

PS. metaObject не катит, так как QGraphicsItem - не наследник от QObject


Название: QGraphicsItem - как добраться до своего метода?
Отправлено: vregess от Апрель 14, 2007, 18:02
Цитата: "troorl"
О, спасибо, вроде помогло. Ещё бы на лету узнавать тип обьекта - было бы вообще замечательно :)

PS. metaObject не катит, так как QGraphicsItem - не наследник от QObject


это тоже можно. Например, средствами самого С++, или ...
А вам зачем нужно на лету узнавать... подробнее можно. Просто тогда можно подобрать соответствующий способ.


Название: QGraphicsItem - как добраться до своего метода?
Отправлено: troorl от Апрель 14, 2007, 20:27
Цитата: "vregess"
Цитата: "troorl"
О, спасибо, вроде помогло. Ещё бы на лету узнавать тип обьекта - было бы вообще замечательно :)

PS. metaObject не катит, так как QGraphicsItem - не наследник от QObject


это тоже можно. Например, средствами самого С++, или ...
А вам зачем нужно на лету узнавать... подробнее можно. Просто тогда можно подобрать соответствующий способ.

У меня в сцене хранится список различных итемов - текстовые, прямоугольники, наследники от QGraphicsItem. В цикле мне нужно обработать итемы определённого типа, в данном случае наследника от QGraphicsItem, остальные трогать мне не нужно.

добавлено спустя 27 минут:

 Я тут немного подумал, как всё это проще сделать. Так вот, у меня возник вопрос. Я плохо разбираюсь в С++, особенно в указателях :) Если я объявил список
QList<QGraphicsItem*> *graphItems
это значит, что в этом списке будут храниться ТОЛЬКО ссылки на итемы, верно? То есть лишней памяти я таким образом не сьем?


Название: Re: QGraphicsItem - как добраться до своего метода?
Отправлено: Steven_Orko от Апрель 14, 2007, 20:52
Цитата: "vregess"


Код:

// YourClass <--- ваш наследник от QGraphicsItem

static_cast<YourClass*>(QGraphicsScene::items().at(i))->yourMethod();


Если уж на то пошло, то никакой не static_cast<>()!!!!!!! а dynamic_cast<>().
Код:

QList<QGraphicsItem*> *graphItems;


Данная запись означает, что ты объявил переменную-указатель на экземпляр класса QList - список, который будет хранить в себе указатели на экземпляры класса QGraphicsItem. Также в этом списке ты можешь хранить и указатели на экземпляры классов-наследников от GraphicsItem.


Название: QGraphicsItem - как добраться до своего метода?
Отправлено: troorl от Апрель 14, 2007, 21:50
Цитата: "Steven_Orko"
Цитата: "vregess"


Код:

// YourClass <--- ваш наследник от QGraphicsItem

static_cast<YourClass*>(QGraphicsScene::items().at(i))->yourMethod();


Если уж на то пошло, то никакой не static_cast<>()!!!!!!! а dynamic_cast<>().
Код:

QList<QGraphicsItem*> *graphItems;


Данная запись означает, что ты объявил переменную-указатель на экземпляр класса QList - список, который будет хранить в себе указатели на экземпляры класса QGraphicsItem. Также в этом списке ты можешь хранить и указатели на экземпляры классов-наследников от GraphicsItem.

Спасибо большое, теперь всё прояснилось.
И тут у меня ещё один вопрос остался нерешённым. Сколько всего перепробовал - никак могу осилить.
Размер итема на сцене определяется значением, которое возвращает boundingRect(). Так вот, если я в конструкторе укажу QRectF, который мне нужен, то на сцене он будет нужного мне размера. Но если я уже после добавления итема на сцену попытаюсь изменить его размер, то ничего не получается...
Вот например:
Код:

QRectF TBackground::boundingRect() const
{
return *bound;
}

Если менять bound, то размер итема на сцене не меняется (верней размер, который всегда прорисовуется). Как решить эту проблему?

ps. извините за чрезмерную настойчивость =)

добавлено спустя 24 минуты:

 Методом научного тыка нашёл prepareGeometryChange(). Вопрос снимается =)


Название: QGraphicsItem - как добраться до своего метода?
Отправлено: vregess от Апрель 15, 2007, 09:20
Цитата: "Steven_Orko"
Цитата: "vregess"


Код:

// YourClass <--- ваш наследник от QGraphicsItem

static_cast<YourClass*>(QGraphicsScene::items().at(i))->yourMethod();


Если уж на то пошло, то никакой не static_cast<>()!!!!!!! а dynamic_cast<>().


Зачем?

добавлено спустя 6 минут:

 
Цитата: "troorl"

И тут у меня ещё один вопрос остался нерешённым. Сколько всего перепробовал - никак могу осилить.
Размер итема на сцене определяется значением, которое возвращает boundingRect(). Так вот, если я в конструкторе укажу QRectF, который мне нужен, то на сцене он будет нужного мне размера. Но если я уже после добавления итема на сцену попытаюсь изменить его размер, то ничего не получается...
Вот например:
Код:

QRectF TBackground::boundingRect() const
{
return *bound;
}

Если менять bound, то размер итема на сцене не меняется (верней размер, который всегда прорисовуется). Как решить эту проблему?

boundingRect() возвращает копию того, что лежит по указателю bound.
Поэтому ниче не получается, тк исходный QRectF не меняется.

Можно сделать:
Код:

QRectF* TBackground::boundingRect() const
{
return bound;
}

Тогда будет возвращяться указатель на QRectF, и можно будет по указателю менять исходный элемент. Но это не правильный путь...
Для подобных дел (изменение параметров и атрибутов класса) нужно делать соответствующие методы, поэтому ты и нашел  prepareGeometryChange().


Название: QGraphicsItem - как добраться до своего метода?
Отправлено: troorl от Апрель 15, 2007, 17:14
Спасибо за поддержку :)

У меня тут возник по ходу дела ещё один вопрос, который я никак не могу решить. У меня на сцене есть много разных итемов. При добавлении итемов размеры сцены увеличиваются - всё как положено. НО! при удалении или уменьшении размеров итемов размеры сцены остаются как были, то есть не уменьшаются. А мне нужно, чтобы её размеры всегда соответствовали её содержанию один в один.
Кроме как удалять итемы и формировать сцену заново пока ничего нормального не придумал :(


Название: QGraphicsItem - как добраться до своего метода?
Отправлено: Steven_Orko от Апрель 16, 2007, 13:13
Цитата: "vregess"
Цитата: "Steven_Orko"
Цитата: "vregess"


Код:

// YourClass <--- ваш наследник от QGraphicsItem

static_cast<YourClass*>(QGraphicsScene::items().at(i))->yourMethod();


Если уж на то пошло, то никакой не static_cast<>()!!!!!!! а dynamic_cast<>().


Зачем?


Ну здесь я бы посоветовал курить стандарт  и трупа страуса )))))


Название: Re: QGraphicsItem - как добраться до своего метода?
Отправлено: d.rogkov от Июнь 04, 2009, 21:42
Цитата: Steven_Orko
Цитата: vregess

Код:
// YourClass <--- ваш наследник от QGraphicsItem

static_cast<YourClass*>(QGraphicsScene::items().at(i))->yourMethod();

Если уж на то пошло, то никакой не static_cast<>()!!!!!!! а dynamic_cast<>().
Код:
QList<QGraphicsItem*> *graphItems;

Данная запись означает, что ты объявил переменную-указатель на экземпляр класса QList - список, который будет хранить в себе указатели на экземпляры класса QGraphicsItem. Также в этом списке ты можешь хранить и указатели на экземпляры классов-наследников от GraphicsItem.
Спасибо большое, теперь всё прояснилось.
И тут у меня ещё один вопрос остался нерешённым. Сколько всего перепробовал - никак могу осилить.
Размер итема на сцене определяется значением, которое возвращает boundingRect(). Так вот, если я в конструкторе укажу QRectF, который мне нужен, то на сцене он будет нужного мне размера. Но если я уже после добавления итема на сцену попытаюсь изменить его размер, то ничего не получается...
Вот например:
Код:
QRectF TBackground::boundingRect() const
{
return *bound;
}
Если менять bound, то размер итема на сцене не меняется (верней размер, который всегда прорисовуется). Как решить эту проблему?

ps. извините за чрезмерную настойчивость =)

добавлено спустя 24 минуты:

 Методом научного тыка нашёл prepareGeometryChange(). Вопрос снимается =)

The boundingRect() function has many different purposes. QGraphicsScene bases its item index on boundingRect(), and QGraphicsView uses it both for culling invisible items, and for determining the area that needs to be recomposed when drawing overlapping items. In addition, QGraphicsItem's collision detection mechanisms use boundingRect() to provide an efficient cut-off. The fine grained collision algorithm in collidesWithItem() is based on calling shape(), which returns an accurate outline of the item's shape as a QPainterPath. - boundingRect() имеет много разных целей. QGraphicsScene базирует сови гр.объекты исходя из того, что вернула boundingRect(), и QGraphicsView, используя QGraphicsScene и boundingRect() для каждого элемента, отбирает "невидимые" гр.элементы, также для определения области которая будет невосприимчива, некликабельна при перекрытии элементов. К тому же, при коллизиях (возмжно говориться о перекрытии), точнее, в функциях их обнаружения используется boundingRect() для обеспечения эффективного отсечения, при наложении объектов с разным приоритетом друг на друга. Интересно то, что алгорит поиска коллизий в collidesWithItem() основывается на вызове shape() и возвращает точную линию описывающую форму гр.объекта. За отрисовку гр.объекта отвечает внутренная переменная типа QPainterPath, при изменении boundingRect() размеры отображаемых даных не изменяются


Название: Re: QGraphicsItem - как добраться до своего метода?
Отправлено: BaltikS от Июнь 05, 2009, 06:34
Очень актуальный ответ. Узнал много нового :)))))


Название: Re: QGraphicsItem - как добраться до своего метода?
Отправлено: mal от Июнь 09, 2009, 20:55
...
Если менять bound, то размер итема на сцене не меняется (верней размер, который всегда прорисовуется). Как решить эту проблему?
...

задай матрицу преобразований и установи ее своему объекту.
Код:
QMatrix matr;
matr.scale(2.0, 2.0);
item->setMatrix(matr);





Название: Re: QGraphicsItem - как добраться до своего метода?
Отправлено: BaltikS от Июнь 10, 2009, 06:41
Ребята, что Вы здесь чушь всякую пишите? Без обид....


Название: Re: QGraphicsItem - как добраться до своего метода?
Отправлено: Rcus от Июнь 10, 2009, 06:54
Мне больше интересно к чему эти приступы некромантии? Зачем поднимать темы двухлетней давности?