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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: векторный граф ред с исп библ QT и VS2008  (Прочитано 7953 раз)
greyreality
Гость
« : Апрель 10, 2011, 17:58 »

Задача: написать графический редактор блок-схем обладающий следующими возможностями
- выбор из меню элемента (прямоугольник(блок процесса),
блок ввода-вывода,
блок начало-конец программы,
ромб(блок условия)
шестиугольник(блок цикла for))
- элементы должны быть получается векторные, чтобы при их выделении можно было изменять размер блока
- обычное растровое перо для внесения надписей внутрь блока и по всей картинке
- предполагается в дальнейшем наличие инструмента распознавания фигуры (алгоритмом Дугласа-Пекера)
- предполагается наличие инструмента выделяющего способ прохождения блок-схемы, исходя из заданных условий


Вопрос: т.к. библиотека новая для меня и из-за недостатка знания...
как организовать структуру программы?
например сначала в main.cpp объявить переменную класса MainWindow(наследование от QMainWindow)
затем в классе MainWindow - описать пункты меню(элементы + открыть + сохранить JPEG)
- объявить в конструкторе переменную класса наследованного от QWidget для создания области рисования
затем в классе области рисования написать функции действия-рисования по каждому пункту из меню

НЕЯСНО как разделить ПЕРО - рисование постоянно нажатой левой клавишей мыши и ФИГУРУ которая должна быть отрисованна путем нажатия клавишы, затем перемещения мыши на необходимое расстояние и отпускания клавиши для получения конечных координат фигуры.

НЕЯСНО как организовать возможность моделирования фигуры изменения размера и цвета.

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

test_qt.zip= симбиоз двух прог. не работающий по невнятным причинам >< , если не трудно разъясните пытались прикрутить функцию открытия изображения в окно для рисования (Qt +VS2008 работает из каталога C:\Qt\ плюс прописать пути до библиотек)
winQT.zip= оригинал окна с рисующей мышью (Qt +VS2008 работает из каталога C:\Qt\ плюс прописать пути до библиотек)

если надо для Qt Creator
Paint.zip= оригинал окна с отрисовкой фигур (Qt Creator)
= оригинал окна с рисующей мышью на Qt Creator можно найти по пути C:\Qt\4.7.2\examples\widgets\scribble\scribble.pro ибо стандартный пример


проги ->  http://ifolder.ru/22883549
« Последнее редактирование: Апрель 10, 2011, 18:03 от greyreality » Записан
alexman
Гость
« Ответ #1 : Апрель 10, 2011, 18:26 »

http://doc.qt.nokia.com/4.7/graphicsview.html
Записан
greyreality
Гость
« Ответ #2 : Апрель 10, 2011, 18:32 »


получается что лучше брать за основу
http://doc.qt.nokia.com/4.5/graphicsview-diagramscene.html
из папки C:\Qt\4.7.2\examples\graphicsview\diagramscene\diagramscene.pro

в принципе я начинала с него только были такие же проблемы с привязыванием ПЕРА


Записан
alexman
Гость
« Ответ #3 : Апрель 10, 2011, 19:30 »

в принципе я начинала с него только были такие же проблемы с привязыванием ПЕРА

Что непонятно? Как делали?
Записан
greyreality
Гость
« Ответ #4 : Апрель 12, 2011, 23:00 »

Цитировать
Что непонятно? Как делали?

за основу кнопки Пера(Pen) была взята кнопка вставки текста(Text) в mainwindows.cpp
Код:
    //! [21] кнопки 
void MainWindow::createToolBox()
{
...
QToolButton *penButton = new QToolButton;
    penButton->setCheckable(true);
////тип кнопки текста
    buttonGroup->addButton(penButton, InsertPenButton);
    penButton->setIcon(QIcon(QPixmap(":/images/pointer.png").scaled(30, 30)));
    penButton->setIconSize(QSize(40, 40));
    QGridLayout *penLayout = new QGridLayout;
    penLayout->addWidget(penButton, 0, 0, Qt::AlignHCenter);
    penLayout->addWidget(new QLabel(tr("Pen")), 1, 0, Qt::AlignCenter);
    QWidget *penWidget = new QWidget;
    penWidget->setLayout(penLayout);
    layout->addWidget(penWidget, 5,0);
...
}

назначаем значение типа кнопки для смены режима рисования (есть режим фигур, текста и теперь пера)
Код:
const int InsertTextButton = 10;//тип кнопки текста
const int InsertPenButton = 20;//тип кнопки пера

в базовом конструкторе окна присваиваем действия по нажатию кнопки
Код:
    /*одноразовое исп-ие кнопки ТЕКСТА нажата и после исп-ия отпущена*/
connect(scene, SIGNAL(textInserted(QGraphicsTextItem*)),
           this, SLOT(textInserted(QGraphicsTextItem*)));
/*одноразовое исп-ие кнопки ПЕРА нажата и после исп-ия отпущена*/
connect(scene, SIGNAL(penInserted(????????????*)),this,SLOT(penInserted(??????????*)));
/code]

[code]
/*! [8] устанавливаем режим сцены обратно на тот режим, который был прежде чем
текст был вставлен.*/
void MainWindow::penInserted(??????????? *)
{   buttonGroup->button(InsertPenButton)->setChecked(false);
    scene->setMode(DiagramScene::Mode(pointerTypeGroup->checkedId()));
}

 я не знаю что писать вместо знаков вопроса, потому что ни один из Classes in the Graphics View Framework не подходит под перо (должна быть возможность получить коор-ты для последующей корректировки)

может быть выбрать  QGraphicsPathItem http://www.doc.crossplatform.ru/qt/4.7.x/qgraphicspathitem.html
или QAbstractGraphicsShapeItem
http://www.doc.crossplatform.ru/qt/4.7.x/qabstractgraphicsshapeitem.html

а для открытия картинки в окне выбрать QGraphicsPixmapItem?
http://www.doc.crossplatform.ru/qt/4.7.x/qgraphicspixmapitem.html
[/code]
Записан
alexman
Гость
« Ответ #5 : Апрель 13, 2011, 07:49 »

Если правильно понял о чем речь, то вам необходимо обрабатывать события сцены, то есть переопределить методы:
Код:
void QGraphicsScene::mousePressEvent ( QGraphicsSceneMouseEvent * mouseEvent ) [virtual protected]
void QGraphicsScene::mouseReleaseEvent ( QGraphicsSceneMouseEvent * mouseEvent ) [virtual protected]
void QGraphicsScene::mouseMoveEvent ( QGraphicsSceneMouseEvent * mouseEvent ) [virtual protected]
...
Записан
greyreality
Гость
« Ответ #6 : Апрель 13, 2011, 20:30 »

Если правильно понял о чем речь, то вам необходимо обрабатывать события сцены, то есть переопределить методы:
Код:
void QGraphicsScene::mousePressEvent ( QGraphicsSceneMouseEvent * mouseEvent ) [virtual protected]
void QGraphicsScene::mouseReleaseEvent ( QGraphicsSceneMouseEvent * mouseEvent ) [virtual protected]
void QGraphicsScene::mouseMoveEvent ( QGraphicsSceneMouseEvent * mouseEvent ) [virtual protected]

Тогда...

Функция void DiagramScene::mousePressEvent управляет событиями НАЖАТИЯ мыши в зависимости от того, в каком режиме находится DiagramScene.
поэтому прописываем действия при режиме ПЕРО
Код:
switch (myMode) {
   case InsertItem:...  //режим вставки фигуры - слева нажата кнопка фигуры
   case InsertLine:...  //режим вставки линии-стрелки - нажата кнопка из верхнего меню
   case InsertText:... //режим вставки текста - слева нажата кнопка текста
   case PenMode:
  /*  НЕОБХОДИМО ПОЛУЧИТЬ НАЧАЛЬНУЮ КООРДИНАТУ ДЛЯ РИСОВАНИЯ ПЕРОМ*/
    break;
...

 В функции void DiagramScene::mouseMoveEvent ПЕРЕМЕЩЕНИЕ мыши. Должны отрисовывать линию если мы в режиме InsertLine и кнопка мыши нажата (линия не равно 0). Как описано в mousePressEvent(), линия рисуется от позиция где мышь была нажата до текущей позиции мыши.
 Если мы в режиме MoveItem, мы вызываем реализацию QGraphicsScene, которая обрабатывает перемещение элементов.
 А если в режиме PenMode то должны рисовать перемещение мыши.
Код:
void DiagramScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
    if (myMode == InsertLine && line != 0) {
        QLineF newLine(line->line().p1(), mouseEvent->scenePos());
        line->setLine(newLine);
    } else
if (myMode == MoveItem) {
        QGraphicsScene::mouseMoveEvent (mouseEvent);
    } else
if (myMode == PenMode)  { ЗДЕСЬ КАК-ТО НА ПОДОБИИ ОТРИСОВКИ line ДОЛЖНЫ
РИСОВАТЬСЯ НОВЫЕ ТОЧКИ  СЛЕДУЯ ЗА ПЕРЕМЕЩЕНИЕМ МЫШИ }
}

void DiagramScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
ОТПУСКАНИЕ МЫШИ
отвечает за определение над нарисованной линией (в режиме InsertLine), наличия фигур
и отрисовывает стрелку, которая их соединяет.прописывать действия для ПЕРА.
Код:
void DiagramScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
{    if (line != 0 && myMode == InsertLine) {
        QList<QGraphicsItem *> startItems = items(line->line().p1());
        if (startItems.count() && startItems.first() == line)   startItems.removeFirst();
        QList<QGraphicsItem *> endItems = items(line->line().p2());
        if (endItems.count() && endItems.first() == line)       endItems.removeFirst();

        removeItem(line);
        delete line;
        if (startItems.count() > 0 && endItems.count() > 0 &&
            startItems.first()->type() == DiagramItem::Type &&
            endItems.first()->type() == DiagramItem::Type &&
            startItems.first() != endItems.first()) {
            DiagramItem *startItem =
                qgraphicsitem_cast<DiagramItem *>(startItems.first());
            DiagramItem *endItem =
                qgraphicsitem_cast<DiagramItem *>(endItems.first());
            Arrow *arrow = new Arrow(startItem, endItem);
            arrow->setColor(myLineColor);
            startItem->addArrow(arrow);
            endItem->addArrow(arrow);
            arrow->setZValue(-1000.0);
            addItem(arrow);
            arrow->updatePosition();
          }
}
else
   if (myMode == PenMode) {
/*НЕОБХОДИМО ЗАКОНЧИТЬ РИСОВАНИЕ  ПЕРОм*/
     }

    line = 0;
    QGraphicsScene::mouseReleaseEvent(mouseEvent);
}

все по прежнему не могу понять КАК СДЕЛАТЬ ЭТО САМОЕ ПЕРО... ведь используем QGraphicsScene а значит привязаны к его классам, а у них нет ничего похожего на перо...
ради интереса было попробованной в первой функции вставить кривую
Код:
case PenMode: //режим вставки кривой - слева нажата кнопка Pen
            path.moveTo(10,10);//какая то кривая для примера рисуется по нажатию на холст
            path.cubicTo(200,80,320,80,480,320);
            addPath(path, QPen(QColor(0, 199, 0)));/*добавляет путь на сцену и возвращает
указатель на него. Геометрия пути определяется путём path, а его перо и кисть
станавливаются равными pen и brush.*/
кривая заданная в первой функции действительно появляется на холсте.

верно ведь была понята мысль о переопределении методов?
Записан
alexman
Гость
« Ответ #7 : Апрель 13, 2011, 20:55 »

Мало что понятно из последнего поста. Вот как можно реализовать это:
Цитировать
НЕЯСНО как разделить ПЕРО - рисование постоянно нажатой левой клавишей мыши

1. Реализуем класс для рисовка набора точек (либо можно использовать QGraphicsPathItem).
2. Реализуем класс - обработчик событий от сцены + хранит указатель на объект из пункта 1.
3. Обрабатываем события и обновляем объект.

Спрашивайте, что не ясно (только по делу, а не с кучей непонятного текста)!?
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


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