Russian Qt Forum
Сентябрь 27, 2024, 14:25 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Перерисовка QGraphicsItem  (Прочитано 18157 раз)
pashazz
Гость
« : Апрель 14, 2009, 10:20 »

Задача такая: залить цветом уже нарисованный QGraphicsItem
Речь идет о интерпретаторе QBasic. https://github.com/pashazz/qtqbasic/tree
Переопределение QGraphicsItem не рассматриваю - фигур много. Если это не единственный вариант
Вот что у меня получилось:
Код
C++ (Qt)
void runWindow::paintEvent(QPaintEvent *e) {
   if (it != 0  && colornum != -1) {
QPainter *p = new QPainter (this);
p->setBrush(QBrush (num2col(colornum)));
it->paint(p, new QStyleOptionGraphicsItem(), this);
it = 0;
   }
}
 

it добывается с помощью ItemAt по координатам x,y. Определяется правильно.
colornum тоже правильно - номер цвета.
Но рисовать не хочет.
Вывод: QPaintEngine::setSystemRect: Should not be changed while engine is active
QPaintEngine::setSystemRect: Should not be changed while engine is active
QPaintEngine::setSystemRect: Should not be changed while engine is active

Подскажите, как сделать правильно. Спасибо.
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #1 : Апрель 14, 2009, 10:36 »

Попробуй так:

Код
C++ (Qt)
void runWindow::paintEvent(QPaintEvent *e) {
   if (it != 0  && colornum != -1) {
       QPainter p (this);
       p.setBrush(QBrush (num2col(colornum)));
       it->paint(&p, new QStyleOptionGraphicsItem(), this);
       it = 0;
   }
}
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
pashazz
Гость
« Ответ #2 : Апрель 14, 2009, 10:42 »

Предупреждения пропали, но цвет не меняется там, где должен. Все так и остается.
Записан
pashazz
Гость
« Ответ #3 : Апрель 14, 2009, 16:35 »

Неужели придется наследовать?
Записан
Rcus
Гость
« Ответ #4 : Апрель 14, 2009, 16:58 »

А в чем проблема в наследовании? Наследовать свои классы от QAbstractShapeItem и рисовать в paint'е при помощи установленных pen()/brush()
Записан
pashazz
Гость
« Ответ #5 : Апрель 14, 2009, 18:00 »

Проблема в том, что нужно подставлять координаты в drawEllipse допустим. А откуда их брать?
Записан
pashazz
Гость
« Ответ #6 : Апрель 14, 2009, 18:00 »

Точнее смысл не в этом. Я не очень понимаю, как это будет выглядеть.
Записан
BaltikS
Гость
« Ответ #7 : Апрель 14, 2009, 19:58 »

pashazz, поставьте конкретнее задачу. Я уверен, что всё можно решить наследованием, главное понять логику того, чего вам в итоге нужно!
Записан
pashazz
Гость
« Ответ #8 : Апрель 14, 2009, 21:03 »

Задача: реализовать QBasic-овский оператор PAINT
там дается точка на плоскости и цвет, которым нужно заполнить фигуру, на которой находится эта точка.
Допустим
PAINT (56,23),7
Найти объект, на котором лежит точка 56,23 и закрасить его цветом 7.
Объекты могут быть: круг, полигон (прямоугольник).
Так понятнее?
Записан
pashazz
Гость
« Ответ #9 : Апрель 14, 2009, 21:07 »

Вот один из вариантов.
Код
C++ (Qt)
//.h
#ifndef MYSCENE_H
#define MYSCENE_H
 
#include <QGraphicsScene>
#include <QPainter>
#include <QtGui>
class myscene : public QGraphicsScene
{
public:
   myscene();
   QColor color; //номер цвета
protected:
   virtual void  drawItems (QPainter *painter, int numItems,
                            QGraphicsItem *items[],
                            const QStyleOptionGraphicsItem options[],
                            QWidget *widget);
 
#endif // MYSCENE_H
 
 
//.cpp
 
#include "myscene.h"
 
void myscene::drawItems(QPainter *painter, int numItems,QGraphicsItem *items[], const QStyleOptionGraphicsItem options[], QWidget *widget) {
 
     for (int i = 0; i < numItems; ++i) {
         // Draw the item
         painter->save();
         painter->setMatrix(items[i]->sceneMatrix(), true);
         painter->setBrush(QBrush (color));
         items[i]->paint(painter, &options[i], widget);
         painter->restore();
     }
 }
 
 

Вываливается с ошибками компиляции
make: Entering directory `/home/pasha/work/QtQBasic'
/usr/bin/make -f Makefile.Debug
make[1]: Entering directory `/home/pasha/work/QtQBasic'
g++ -c -m64 -pipe -g -Wall -W -D_REENTRANT -DQT_OPENGL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/opt/qtsdk-2009.01/qt/mkspecs/linux-g++-64 -I. -I/opt/qtsdk-2009.01/qt/include/QtCore -I/opt/qtsdk-2009.01/qt/include/QtGui -I/opt/qtsdk-2009.01/qt/include/QtOpenGL -I/opt/qtsdk-2009.01/qt/include -I/usr/X11R6/include -Idebug -I. -o debug/myscene.o myscene.cpp
myscene.cpp:3: ошибка: избыточная квалификация ‘myscene::’ элемента ‘drawItems’
myscene.cpp:3: ошибка: ‘void myscene::drawItems(QPainter*, int, QGraphicsItem**, const QStyleOptionGraphicsItem*, QWidget*)’ cannot be overloaded
myscene.h:16: ошибка: with ‘virtual void myscene::drawItems(QPainter*, int, QGraphicsItem**, const QStyleOptionGraphicsItem*, QWidget*)’
myscene.cpp:13: ошибка: expected `}' at end of input
myscene.cpp:13: ошибка: expected unqualified-id at end of input
make[1]: *** [debug/myscene.o] Ошибка 1
make[1]: Leaving directory `/home/pasha/work/QtQBasic'
make: *** [debug] Ошибка 2
make: Leaving directory `/home/pasha/work/QtQBasic'
Exited with code 2.
Error while building project QtQBasic
When executing build step 'Make'
Записан
pashazz
Гость
« Ответ #10 : Апрель 14, 2009, 21:09 »

В общем я совсем запутался.
Подскажите другое решение.
и да: http://github.com/pashazz/qtqbasic/tree
Записан
BaltikS
Гость
« Ответ #11 : Апрель 15, 2009, 07:00 »

Могу тебе подсказать алгоритм решения твоей задачи....
1) оставить сцену в покое(не нужно от неё наследоваться);
2) унаследуйся от QGraphicsItem и добавь в нём переменные для хранения варианта (круг, полигон) и цвета.
Например h-файл может выглядеть так:
Код:
class MyItem : public QGraphicsItem
{
public:
             enum TypeObject {Circle, Rectangle, Polygon);                 // типы наших объектов

MyItem( QGraphicsItem * parent);

             void setColor(int);               // передаём цвет

int type() const { return UserType+1; } // не забываем энту строчку!!!

protected:
     // переопредляем методы
     virtual QRectF boundingRect () const; // размер прямоугольной области
     virtual void paint ( QPainter * painter,
const QStyleOptionGraphicsItem * option, QWidget * widget = 0 );// отрисовка нашего объекта
     virtual QPainterPath shape () const ; // область фокуса

private:
     TypeObject _type;   // тип нашего объекта
     int _color;    // цвет нашего объекта
3) переопредели методы boundingRect(), shape() и paint();
4) добавляем на сцену нужное количество твоих элементов (например в цикле случайным образом);
5) напиши в главной форме свою функцию paint.
Например:
Код:
void paint(const QPoint point, int color)
{
   ...
   QList<QGraphicsItem *> list = scene->items(point);
   for (int i = 0; i < list.size(); ++i)
       qgraphicsitem_cast<MyItem *>(list.at(i))->setColor(color);
5) определи на форме событие, по которому будет вызываться твоя фунция paint...
Записан
xokc
Птица говорун
*****
Offline Offline

Сообщений: 976



Просмотр профиля
« Ответ #12 : Апрель 15, 2009, 07:57 »

Я бы наследовался дважды - базовый класс с цветом и уже от него классы для круга и прямоугольника с перепоределенным paint.
Записан
Rcus
Гость
« Ответ #13 : Апрель 15, 2009, 08:20 »

Круто, вы только что заново изобрели QGraphicsAbstractShapeItem, QGraphicsEllipseItem, QGraphicsRectItem и QGraphicsPolygonItem. oh wait...
Записан
BaltikS
Гость
« Ответ #14 : Апрель 15, 2009, 09:50 »

Ну да, правильно было бы от QGraphicsAbstractShapeItem наследоваться....

Хотя можно вообще не городить огород, а взять и преобразовать к типу, указанному выше, и, задавать его цвет...
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.138 секунд. Запросов: 23.