crossplatform.ru

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

 
Ответить в данную темуНачать новую тему
> Проблема с QGraphicsView и QGraphicsScene
NordWest
  опции профиля:
сообщение 31.3.2011, 13:40
Сообщение #1


Студент
*

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

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




Репутация:   0  


Пытаюсь написать диалог с выбором цветов для набора элементов, отображаемых в основном окне программы. Для этого создал в дизайнере диалоговое окно, в которое поместил QGraphicsView. Мне нужно, чтобы в нём отображался пример элементов основного окна с элементами выбранных цветов.

В разделе private класса окна объявил объект QGraphicsScene
QGraphicsScene *scene;


В конструкторе так:
ui->setupUi(this);
ui_grView = qFindChild<QGraphicsView *>(this, "grView");
...
scene = new QGraphicsScene;
ui_grView->setScene(scene);
ui_grView->show();
connect(scene, SIGNAL(changed(QList<QRectF>)), ui_grView, SLOT(updateScene(QList<QRectF>)));

bgCol.setRgb(Qt::black);
bgBrush.setColor(bgCol);
scene->setBackgroundBrush(bgBrush);
...


Не знаю, нужен ли тут connect или задав сцену QGraphicsView я уже задаю связь обновлений. В общем, так не работает, черный фон не появляется. Получилось только если три последних строчки вставить между созданием scene и установкой её объекту ui_grView. Но мне то нужно задать обновление отображения при смене того же цвета фона или цвета одного из других элементов.

Выше представлен последний вариант, который я пробовал. Первоначально у меня был вариант из одного примера с переопределением paintEvent:

void setupMarksColor::paintEvent(QPaintEvent *event)
{
      updateBaseImage();
}

void setupMarksColor::updateBaseImage()
{
    bgBrush.setColor(bgCol);
    scene->setBackgroundBrush(bgBrush);
    
    QList <QRectF> rList;
    rList << ui_grView->sceneRect();
    ui_grView->updateScene(rList);
}


Т.е. пытался обновлять сцену без connect'a в конструкторе. Но тоже пусто. Не очень я понимаю взаимоотношения QGraphicsView и QGraphicsScene и примеры как-то не помогают. Подскажите что исправить и почему, если не сложно.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
abc
  опции профиля:
сообщение 31.3.2011, 20:24
Сообщение #2


Участник
**

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

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




Репутация:   4  


очень не понял проблему
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
NordWest
  опции профиля:
сообщение 1.4.2011, 0:57
Сообщение #3


Студент
*

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

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




Репутация:   0  


Так. Я не понимаю, как заставить сцену обновиться с новым цветом. И что вообще значат эти цвета.

Вот у меня QGraphicsView в окне сплошь белый. Как его залить черным фоном? scene->setBackgroundBrush меняет не цвет фона, так? Это некая фоновая кисть. Т.е. если рисуешь зелёный кружок, то он будет нарисован на фоне цвета этой кисти. Или нет? Чтобы полностью белый элемент QGraphicsView сделать чёрным нужно ему какой то параметр указать "чёрный" или взять чёрную кисть и добавить в сцену прямоугольник с размерами во всю сцену.

Всё равно непонятно объяснил, потому что сам плохо понял схему QGraphicsView <-> QGraphicsScene. Лучше скажу что надо. В диалоговом окне задается 5 цветов, фон и 4 цвета для примерных кружков на этом фоне. Нужно нарисовать такое превью, чтобы показать как эти разноцветные кружки будут видеться на выбранном фоне.

Создал я элемент QGraphicsView в дизайнере. Создал QGraphicsScene. Дальше как? Мне нужно фон самому нарисовать, условно добавив прямоугольник или scene->setBackgroundBrush действительно заливает данной кистью весь фон? Те 4 кружка нужно один раз создать и добавить, а потом как-то менять им цвета? Если я поменяю что-то в scene, что мне нужно, чтобы обновилась и картинка?

Где-то так, надеюсь на понимание.

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
abc
  опции профиля:
сообщение 1.4.2011, 13:27
Сообщение #4


Участник
**

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

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




Репутация:   4  


сцене делаешь setBackgroundBrush
твои кружки это разновидность QGraphicsItem - QGraphicsEllipseItem
чтобы кружкам задать окраску - setBrush
Про QGraphicsView можно в основном забыть с момента, как установил ему сцену
все дела делает QGraphicsScene
для QGraphicsView, полезно устанавливать сглаживание (скошенные линии не будут напоминать зигзаги):
ui->graphicsView->setRenderHints(QPainter::Antialiasing);
paintEvent тоже вряд ли нужен тебе для твоей задачи
Апдейтить сцену не нужно
подробности:
http://doc.crossplatform.ru/qt/4.6.x/graphicsview.html

С уважением, ЗигЗаг МакКряк :hi:
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
NordWest
  опции профиля:
сообщение 1.4.2011, 19:57
Сообщение #5


Студент
*

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

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




Репутация:   0  


Спасибо за ссылку. Для общего представления полезно, но конкретных ответов я там не нашел.

Много чего перепробовал, много непоняток. То одно не рисуется, то другое. То фон черный, кружка нет, то наоборот.

Но всё таки получилось. Вот рабочий вариант:
Раскрывающийся текст
#include "setupmarkscolor.h"
#include "ui_setupmarkscolor.h"

setupMarksColor::setupMarksColor(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::setupMarksColor)
{
    ui->setupUi(this);


    ui_grView = qFindChild<QGraphicsView *>(this, "grView");
    ui_ipixBtn = qFindChild<QPushButton *>(this, "ipixBtn");
    ui_catBtn = qFindChild<QPushButton *>(this, "catBtn");
    ui_refBtn = qFindChild<QPushButton *>(this, "refBtn");
    ui_objBtn = qFindChild<QPushButton *>(this, "objBtn");
    ui_bgBtn = qFindChild<QPushButton *>(this, "bgBtn");


    bgCol = Qt::black;
    ipixCol = Qt::yellow;
    catCol = Qt::blue;
    refCol = Qt::red;
    objCol = Qt::green;



    ipixPen.setColor(ipixCol);
    catPen.setColor(catCol);
    refPen.setColor(refCol);
    objPen.setColor(objCol);

    scene = new QGraphicsScene;
    ui->grView->setRenderHints(QPainter::Antialiasing);
    ui_grView->setScene(scene);
    ui_grView->show();

    scene->setBackgroundBrush(bgCol);

    QRect scR = ui_grView->rect();

    int x0, dx;

    qDebug() << QString("width= %1\n").arg(scR.width());
    dx = scR.width()/4.0;
    x0 = -1.5*dx;

    ipixEll = new QGraphicsEllipseItem(x0, 0, 10, 10);
    scene->addItem(ipixEll);

    x0 += dx;
    catEll = new QGraphicsEllipseItem(x0, 0, 10, 10);
    scene->addItem(catEll);
    x0 += dx;
    refEll = new QGraphicsEllipseItem(x0, 0, 10, 10);
    scene->addItem(refEll);
    x0 += dx;
    objEll = new QGraphicsEllipseItem(x0, 0, 10, 10);
    scene->addItem(objEll);

    ipixEll->setPen(ipixPen);
    catEll->setPen(catPen);
    refEll->setPen(refPen);
    objEll->setPen(objPen);

}

setupMarksColor::~setupMarksColor()
{
    delete ui;
}

void setupMarksColor::changeEvent(QEvent *e)
{
    //qDebug() << "changeEvent\n";
    QDialog::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
        ui->retranslateUi(this);
        break;
    default:
        break;
    }
}

void setupMarksColor::on_bgBtn_clicked()
{
    QColorDialog bgColDlg;//(bgCol);
    bgCol = bgColDlg.getColor(bgCol);
    scene->setBackgroundBrush(bgCol);
}

void setupMarksColor::on_ipixBtn_clicked()
{
    QColorDialog bgColDlg;
    ipixCol = bgColDlg.getColor(ipixCol);
    ipixPen.setColor(ipixCol);
    ipixEll->setPen(ipixPen);
}

void setupMarksColor::on_catBtn_clicked()
{
    QColorDialog bgColDlg;
    catCol = bgColDlg.getColor(catCol);
    catPen.setColor(catCol);
    catEll->setPen(catPen);
}

void setupMarksColor::on_refBtn_clicked()
{
    QColorDialog bgColDlg;
    refCol = bgColDlg.getColor(refCol);
    refPen.setColor(refCol);
    refEll->setPen(refPen);
}

void setupMarksColor::on_objBtn_clicked()
{
    QColorDialog bgColDlg;
    objCol = bgColDlg.getColor(objCol);
    objPen.setColor(objCol);
    objEll->setPen(objPen);
}


Чтобы фон нормально окрасился оказывается надо в метод setBackgroundBrush передавать не QBrush а QColor. Вот как догадаться об этом?

Для объектов QGraphicsEllipseItem можно в методе setPen указать и QPen и QColor.

Ну главное удалось добиться результата, хотя и не очень понятно как.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
abc
  опции профиля:
сообщение 1.4.2011, 20:15
Сообщение #6


Участник
**

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

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




Репутация:   4  


Цитата(NordWest @ 1.4.2011, 20:57) *
setBackgroundBrush передавать не QBrush а QColor

не правда, в документации QBrush, а вот QBrush строить из QColor. И я так сделал, всё прекрасно

setPen рисует ободок итема, setBrush фон

Если что-то не получается, разберись - почему. поэкспериментируй
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
NordWest
  опции профиля:
сообщение 1.4.2011, 20:43
Сообщение #7


Студент
*

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

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




Репутация:   0  


Ага. Т.е. он фаторматически подставил QBrush(QColor).
Но тогда непонятно отчего не работает:
bgBrush.setColor(bgCol);
scene->setBackgroundBrush(bgBrush);


Фон белый.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
abc
  опции профиля:
сообщение 1.4.2011, 21:14
Сообщение #8


Участник
**

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

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




Репутация:   4  


void QColor::setRgb ( QRgb rgb )
а ты делаешь
setRgb(Qt::black);
думаю, поэтому

Qt::black относится к Qt::GlobalColor
очевидно, что QRgb не равно Qt::GlobalColor

почему компилятор не закричал..
наверное потому, что setRgb ждёт int, и в лице Qt::black его получает...
т.к. про QRgb я читаю:
An ARGB quadruplet on the format #AARRGGBB, equivalent to an unsigned int.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

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


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




RSS Текстовая версия Сейчас: 21.9.2019, 16:00