crossplatform.ru

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

2 страниц V  < 1 2  
Ответить в данную темуНачать новую тему
> [Решено] Рисование во View?, Как нарисовать что-нибудь изменяющееся минуя сцену?
Litkevich Yuriy
  опции профиля:
сообщение 27.3.2010, 20:26
Сообщение #11


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

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




Репутация:   94  


Тут всё по-русски: Описание класса QRect
Цитата
Мы рекомендуем вам использовать x() + width() и y() + height(), чтобы найти истинный нижний-правый угол, и избегать использования функций right() и bottom().


Проще написать так:
painter.drawRect(rect().adjusted(0, 0, 1, 1));
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Obey-Kun
  опции профиля:
сообщение 27.3.2010, 21:13
Сообщение #12


Студент
*

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

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




Репутация:   0  


Цитата
painter.drawRect(rect().adjusted(0, 0, 1, 1));

Да уж, по-индусски получилось... спасибо :).

только painter.drawRect(rect().adjusted(0, 0, -1, -1)) :)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 27.3.2010, 21:20
Сообщение #13


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

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




Репутация:   94  


Цитата(Obey-Kun @ 28.3.2010, 0:13) *
0, 0, -1, -1
почему минус, QRect ведь возвращает укороченый размер на еденицу, в отличие от QRectF, и нужно его на единицу по каждой координате увеличить
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Obey-Kun
  опции профиля:
сообщение 27.3.2010, 21:44
Сообщение #14


Студент
*

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

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




Репутация:   0  


По ходу, последняя проблема осталась. Так как создание подобных вещей мне нужно для визуализации инструментов, используемых пользователем (например, чтобы рисовать рамку, пока пользователь выделяет область), то начальная точка может лежать вне видимой зоны.
Попытался дать ему верхнюю левую точку в отрицательных координатах и получилась такая штука: http://rghost.ru/1257920/image.png

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

Вот тут также видно, что он затирает оконные декорации: http://rghost.ru/1257959/image.png (это я сделал очень большой прямоугольник).

Как тут быть?

Проблема решена, надо было банально делать m_recttest = new MyRectangle(viewport()), а не m_recttest = new MyRectangle(this)

Цитата(Litkevich Yuriy @ 27.3.2010, 21:20) *
Цитата(Obey-Kun @ 28.3.2010, 0:13) *
0, 0, -1, -1
почему минус, QRect ведь возвращает укороченый размер на еденицу, в отличие от QRectF, и нужно его на единицу по каждой координате увеличить

Рассмотрим по частям.
painter.drawRect(rect().adjusted(0, 0, -1, -1));

Не знаю, в чём дело, если честно, то лень разбираться, но работает как надо оно именно так, а не для +1 +1.

Цитата
Проблема решена, надо было банально делать m_recttest = new MyRectangle(viewport()), а не m_recttest = new MyRectangle(this)

И вообще, рисовать в самом вью было глупой идеей, разумеется надо было рисовать во viewport.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 27.3.2010, 21:58
Сообщение #15


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

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




Репутация:   94  


Obey-Kun, для инструмента выделения, я бы всё таки посмотрел, как это самое выделение сделано в QGraphicsView. Я думаю это не должен быть отдельный виджет.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Obey-Kun
  опции профиля:
сообщение 27.3.2010, 22:30
Сообщение #16


Студент
*

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

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




Репутация:   0  


В смысле? Стандартный метод выделения — QRubberBand, это обычный виджет, унаследованный от QWidget. Имеет свой event рисования. Так что подход полностью схожий. И форма, кстати, тоже через setGeometry меняется. Или ты о чём-то другом?

Кстати, ещё один подводный камень в использовании setGeometry. Если мы ставим жирный Pen или врубаем antialiasing, то он не влазит в свою геометрию. Ну это ясно, просто нужно переопределить setGeometry и вызывать там QWidget::setGeometry с учётом толщины линии. Ну и плюс переопределить rect(), чтобы возвращать нужное значение. Как-то так. Или я неправильно мыслю?

Сообщение отредактировал Obey-Kun - 28.3.2010, 0:29
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 27.3.2010, 23:18
Сообщение #17


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9669
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

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




Репутация:   94  


Цитата(Obey-Kun @ 28.3.2010, 1:30) *
Стандартный метод выделения — QRubberBand
Вот я посмотрел в исходник QGraphicsView, а там QRubberBand не используется.
Смотри начиная с метода:
void QGraphicsView::mousePressEvent(QMouseEvent *event)
И до:
void QGraphicsView::paintEvent(QPaintEvent *event)
Тип выделения хранится во внутренней переменной d->dragMode

В методе:
void QGraphicsView::mouseReleaseEvent(QMouseEvent *event)
Ещё посылается сообщение сцене, зачем и с каким содержимым не вникал
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Obey-Kun
  опции профиля:
сообщение 28.3.2010, 0:09
Сообщение #18


Студент
*

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

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




Репутация:   0  


Странно, и правда рисуют напрямую: http://qt.gitorious.org/qt/qt/blobs/master...ew.cpp#line3441


Причём код почти в точности повторяет код рисования из QRubberBand.

Если честно, не понимаю, зачем они так сделали. Ну разве что ради скорости. Более логичным мне кажется использование отдельного объекта. Да и работать так удобнее было бы. Можно сделать вот так:
class AbstarctInstrument : public QWidget
{
public:
    AbstarctInstrument(QWidget* parent = 0);

    /**
     * Функция, которую следует вызывать, когда юзер отпустил мышку
     * после растяжения инструмента. Тут инструмент делает, то что от
     * него требуется (например, говорит сцене родителя выделить область)
     * и удаляет сам себя
     */
    virtual void workDone();
protected:
    virtual void paintEvent(QPaintEvent* );
};


а вообще, вместо workDone проще использовать деструктор :)
Мне тут использование объекта, который может хранить логику своих действий, больше нравится. Логичнее так, что ли. Да и код view не будет перегружаться лишними вещами. Он лишь будет создавать нужный инструмент при нажатии нужной кнопки мыши (а так как все инструменты унаследованы от одного класса, то можно будет хранить указатель на активный инструмент в QAbstactInstrument *m_instrument), при передвижении мыши делает setGeometry, ну а при отпускании запускает деструктор. Просто и со вкусом.

Сообщение отредактировал Obey-Kun - 28.3.2010, 0:59
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

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


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




RSS Текстовая версия Сейчас: 20.4.2024, 7:03