crossplatform.ru

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

2 страниц V   1 2 >  
Ответить в данную темуНачать новую тему
> определение размеров виджета при использовании QPicture
Litkevich Yuriy
  опции профиля:
сообщение 26.12.2009, 1:00
Сообщение #1


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

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

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




Репутация:   94  


Пытаюсь рисовать на виджете с использованием QPicture.
void PictureViewer::paintEvent(QPaintEvent*)
{
    QPainter painter;
    if (pic){
        painter.begin(this);
        painter.drawPicture(QPoint(0, 0), *pic);
        painter.end();
    }
    
}
здесь pic - указатель на QPicture.

QPicture я загружаю из файла. На основе QPicture::boundingRect().size(), загруженного рисунка, изменяю размер виджета.
Однако рисунок рисовался с отступом от краёв исходного виджета (рисовальщика) по этому получаю такое:
Прикрепленное изображение
, если увеличить размеры виджета мышкой, то видно весь рисунок:
Прикрепленное изображение


Вопрос:
Как определить отступ сверху и слева от края виджета, до рисунка.

Была мысль спросить у рисовальщика (QPainter'а) минимальную координату, где он побывал, но такого метода я не нашёл.

На всякий случай проект прикрепил: Прикрепленный файл  PictureViewer.zip ( 3,89 килобайт ) Кол-во скачиваний: 176

Файлы:
painter1.log
painter2.log
тестовые, для загрузки.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Kagami
  опции профиля:
сообщение 26.12.2009, 9:27
Сообщение #2


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

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

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




Репутация:   9  


Юра, ты меня удивляешь. Есть же функции QWIdget::map*().
Так как у тебя рисовальщик лежит в компоновке и он становится его родительским виджетом, то самый простой способ - вызвать у рисовальщика mapToParent(QPoint(0,0)) - не подходит. Вариантов есть два. Либо хранить в рисовальщике указатель на объект Window и использовать mapTo(window, QPoint(0,0)), либо перебирать родительские виджеты в цикле, пока не дойдем до последнего:
   QWidget* topParent = parentWidget();
   while (topParent->parentWidget())
      topParent = topParent->parentWidget();
а затем mapTo(topParent, QPoint(0,0)).

Сообщение отредактировал Kagami - 26.12.2009, 9:33
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 26.12.2009, 12:49
Сообщение #3


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

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

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




Репутация:   94  


Kagami, не понял.
Я рисую с координат (0, 0) самого виджета.
В итоге мне нужно установить виджету размер, такой, чтобы весь рисунок помещался.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Kagami
  опции профиля:
сообщение 26.12.2009, 14:00
Сообщение #4


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

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

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




Репутация:   9  


Ты про компоновку забываешь - window -> mainLayout -> viewer. А ведь у нее свои поля есть. Поэтому нулевая точка рисовальщика на viewer'е будет смещена относительно (0,0) виджета window.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 26.12.2009, 15:01
Сообщение #5


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

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

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




Репутация:   94  


Меня не интерисует виджет window.
При изменении размеров окна я вижу ту куртинку, какую создавал (сохранил в файле).
Я умышленно покрасил фон виджета PictureViewer, чтобы видеть его размеры.
Цитата(Litkevich Yuriy @ 26.12.2009, 4:00) *
Как определить отступ сверху и слева от края виджета, до рисунка.
речь идёт о PictureViewer, на котором я рисую. под рисунком я понимаю QPicture, который рисуется рисовальщиком (QPainter).
Я рисую по координатам (0, 0):
painter.drawPicture(QPoint(0, 0), *pic);
, чтобы воспроизвести рисунок, так, как он был в оригинале.

При рисовании компоновщики не играют ни какой роли, равно как и наличие родительского виджета. PictureViewer может быть единственным виджетом (окном верхнего уровня)

Вот этот размер меня интерисует:
Прикрепленное изображение
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Kagami
  опции профиля:
сообщение 26.12.2009, 19:26
Сообщение #6


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

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

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




Репутация:   9  


Юр, что бы до конца прояснить ситуацию, при создании этих рисунков, они рисовались с точки (0, 0) или со смещением, которое ты и хочешь выяснить?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 26.12.2009, 20:03
Сообщение #7


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

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

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




Репутация:   94  


Цитата(Kagami @ 26.12.2009, 22:26) *
они рисовались с точки (0, 0
рисовались так:
    virtual void paintEvent(QPaintEvent*)
    {
        QPicture    pic;
        QPainterPath path;
        QPointF      pt1(width(), height() / 2);
        QPointF      pt2(width() / 2, -height());
        QPointF      pt3(width() / 2, 2 * height());
        QPointF      pt4(0, height() / 2);
        path.moveTo(pt1);
        path.cubicTo(pt2, pt3, pt4);/**/

        QRect rect(width() / 4, height() / 4, width() / 2, height() / 2);
        path.addRect(rect);
        path.addEllipse(rect);

        QPainter painter;
        qDebug() << "---------- record ------------";
        painter.begin(&pic);
        painter.setRenderHint(QPainter::Antialiasing, true);
        painter.setPen(QPen(Qt::blue, 6));
        painter.drawPath(path);
        painter.end();
        if (!pic.save("./painter.log")){
            qDebug() << "anable to save log-file";
        }
        
        qDebug() << "---------- play ------------";
        painter.begin(this);
        painter.drawPicture(QPoint(0, 0), pic);
        painter.end();
        
    }


Это переделанный пример из книги Шлее.

как я понимаю, координаты именно (0, 0)
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Kagami
  опции профиля:
сообщение 26.12.2009, 21:30
Сообщение #8


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

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

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




Репутация:   9  


Чуть-чуть покопался в исходниках QPicture. Заметил что boundRect зашивается в файл при сохранении. Надо посмотреть как они его считают, может какая идея и придет.

UPD. Все оказалось гораздо проще. В файле, куда сохранен QPicture, зашит левый верхний угол ограничивающего прямоугольника и его высота и ширина. Как их считать написано в /opt/qtsdk-2009.05/qt/src/gui/image/qpicture.cpp, смотри функцию QPicturePrivate::checkFormat()

UPD2. Совсем забыл - ответ на твой первоначальный вопрос:
Цитата
int top = pic->boundingRect().y();
int left = pic->boundingRect().x();


Сообщение отредактировал Kagami - 26.12.2009, 22:21
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 26.12.2009, 23:04
Сообщение #9


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

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

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




Репутация:   94  


Цитата(Kagami @ 27.12.2009, 0:30) *
Надо посмотреть как они его считают
я его чуть ли не наизусть выучил

Цитата(Kagami @ 27.12.2009, 0:30) *
В файле, куда сохранен QPicture, зашит левый верхний угол ограничивающего прямоугольника
блин, как-то я то из виду упустил, что у прямоугольника начальная координата может быть не нулевой.

Kagami, спасибо большое!, почти сутки трахмучаюсь


Нынешний фрагмент кода от моего первоначального исходника:
PictureViewer::PictureViewer(const QPicture &picture, QWidget *pwgt) : QWidget(pwgt)
{
    *pic = picture;
    minSize = pic->boundingRect().size();
    
    int top = pic->boundingRect().y();
    int left = pic->boundingRect().x();
    qDebug() << "X =" << left << " | " << "Y =" << top;
    minSize += QSize(left, top);
}

void PictureViewer::refrash()
{
    minSize = pic->boundingRect().size();
    qDebug() << "PictureViewer::refrash...........minSize =" << minSize << "    size() =" << size();
    int top = pic->boundingRect().y();
    int left = pic->boundingRect().x();
    qDebug() << "X =" << left << " | " << "Y =" << top;
    minSize += QSize(left, top);    
        
    //resize(minSize);
    update();
    updateGeometry();
}


Вот как теперь:
Прикрепленное изображение
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Kagami
  опции профиля:
сообщение 26.12.2009, 23:16
Сообщение #10


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

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

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




Репутация:   9  


Кстати, а почему бы тебе не выводить рисунок со смещением?
Цитата
int top = pic->boundingRect().y();
int left = pic->boundingRect().x();
painter.drawPicture(QPoint(-left, -top), *pic);
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

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


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




RSS Текстовая версия Сейчас: 27.12.2024, 15:48