Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: neosapient от Октябрь 13, 2009, 15:15



Название: Как лучше организовать интерактивныю блок-схему.
Отправлено: neosapient от Октябрь 13, 2009, 15:15
Всем добрый день.

Хочу с вами посоветоваться, как правильнее решать поставленую передомной задачу.

Есть блок-схема, на которой отображено взаимодействие между серверами (Lan). Каждый сервер отображен иконкой с компьютером. А передача данных между серверами отображена стрелкой.

Моя программа умеет пинговать эти сервера и опрашивать их о соединении с другими компьютерами.

Я хочу  сделать интерактивную блок-схему, чтобы при потере связи с сервером или обрыве связи между серверами соответствующие элементы блок-схемы начали гореть красным.

С помощью какого виджета или компонента QT4 будет проще отображать мигание стрелок и мониторов? Возможно есть исходники с примерами?


Название: Re: Как лучше организовать интерактивныю блок-схему.
Отправлено: BRE от Октябрь 13, 2009, 15:24
Я бы сразу смотрел в сторону QGraphicsScene + QGraphicsView.


Название: Re: Как лучше организовать интерактивныю блок-схему.
Отправлено: Khs от Октябрь 13, 2009, 16:10
Может это чем-то поможет:

http://qt-apps.org/content/show.php/NetEmul?content=109986


Название: Re: Как лучше организовать интерактивныю блок-схему.
Отправлено: shadone от Октябрь 14, 2009, 13:43
посмотри стандартный пример который идет вместе с Qt - examples/graphicsview/diagramscene


Название: Re: Как лучше организовать интерактивныю блок-схему.
Отправлено: neosapient от Октябрь 15, 2009, 10:05
Сейчас рассмотриваю примеры diagramscene и undoframework.

А есть пример, как можно заставить мигать рисунок или набор графических приметивов? В разделе анимации ничего подходящего не нашел, может пропустил? Просто не хочется делать велосипед с таймером, если есть готовое решение.


Название: Re: Как лучше организовать интерактивныю блок-схему.
Отправлено: shadone от Октябрь 15, 2009, 14:59
Сейчас рассмотриваю примеры diagramscene и undoframework.

А есть пример, как можно заставить мигать рисунок или набор графических приметивов? В разделе анимации ничего подходящего не нашел, может пропустил? Просто не хочется делать велосипед с таймером, если есть готовое решение.
старый способ - QTimeline (http://doc.qt.nokia.com/4.6-snapshot/qtimeline.html). Рекомендуемый способ - Qt Animation API (http://doc.qt.nokia.com/4.6-snapshot/qt4-6-intro.html#animation-framework) который является частью Qt 4.6


Название: Re: Как лучше организовать интерактивныю блок-схему.
Отправлено: neosapient от Октябрь 16, 2009, 12:54
Цитировать
старый способ - QTimeline. Рекомендуемый способ - Qt Animation API который является частью Qt 4.6

Примеры, которые я видел, демонстрируют маштабирование и изменение положения графического объека. Подскажите пример, в котором графический объект меняет цвет с оределенным периодом времени (мигает)?


Название: Re: Как лучше организовать интерактивныю блок-схему.
Отправлено: shadone от Октябрь 16, 2009, 13:02
Цитировать
старый способ - QTimeline. Рекомендуемый способ - Qt Animation API который является частью Qt 4.6

Примеры, которые я видел, демонстрируют маштабирование и изменение положения графического объека. Подскажите пример, в котором графический объект меняет цвет с оределенным периодом времени (мигает)?
Animation API позволяет анимировать изменение любых свойств (Q_PROPERTY) объекта. Просто храните цвет в виде свойства и переключайте состояние (state).


Название: Делаем мигающий элемент блок-схемы.
Отправлено: neosapient от Октябрь 21, 2009, 10:28
Пробую сделать пример мигающего круга.
Мигание собираюсь реализовать через кисть разных цветов.

Сделал наследника от QGraphicsEllipseItem и пробую релизовать анимацию
Код:
#include <QtCore>
#include <QtGui>

class MyGraphicsEllipseItem : public QObject, public QGraphicsEllipseItem
{
    Q_OBJECT
    Q_PROPERTY(QBrush brush READ brush WRITE setBrush)
public:
   MyGraphicsEllipseItem(const QRectF &rect)
        : QObject(), QGraphicsEllipseItem(rect)
    {
        setCacheMode(DeviceCoordinateCache);
    }
};

int main(int argc, char **argv)
{
QApplication app(argc, argv);
QObject *ball = new MyGraphicsEllipseItem(QRectF(0, 0, 20, 20));

QPropertyAnimation animation(ball, "brush");
animation.setDuration(10000);

animation.setKeyValueAt(0, QBrush(QColor(255,0,0)));
animation.setKeyValueAt(0.8, QBrush(QColor(0,255,0)));
animation.setKeyValueAt(1, QBrush(QColor(0,0,255)));

QGraphicsScene *scene = new QGraphicsScene();
scene->setSceneRect(0, 0, 220, 220);
scene->addItem((QGraphicsItem*)ball);

QGraphicsView *view = new QGraphicsView(scene);
view->show();

     return app.exec();
}

При сборке выдаються ошибки линковки
Цитировать
1>main.obj : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall MyGraphicsEllipseItem::metaObject(void)const " (?metaObject@MyGraphicsEllipseItem@@UBEPBUQMetaObject@@XZ)
1>main.obj : error LNK2001: unresolved external symbol "public: virtual void * __thiscall MyGraphicsEllipseItem::qt_metacast(char const *)" (?qt_metacast@MyGraphicsEllipseItem@@UAEPAXPBD@Z)
1>main.obj : error LNK2001: unresolved external symbol "public: virtual int __thiscall MyGraphicsEllipseItem::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@MyGraphicsEllipseItem@@UAEHW4Call@QMetaObject@@HPAPAX@Z)
1>debug\New Folder (6).exe : fatal error LNK1120: 3 unresolved externals
Что упустил ?


Название: Re: Как лучше организовать интерактивныю блок-схему.
Отправлено: BRE от Октябрь 21, 2009, 10:31
Добавь в файл main.cpp:
#include "main.moc"

и сделай:
qmake
make


Название: Делаем мигающий элемент блок-схемы.
Отправлено: neosapient от Октябрь 21, 2009, 11:03
Проект собирается, но в программе ничего не происходит - круг своего цвета не меняет.

Код:
#include <QtCore>
#include <QtGui>

class MyGraphicsEllipseItem : public QObject, public QGraphicsEllipseItem
{
Q_OBJECT
Q_PROPERTY(QBrush brush READ brush WRITE setBrush)
public:
MyGraphicsEllipseItem(const QRectF &rect)
: QObject(), QGraphicsEllipseItem(rect)
{
setCacheMode(DeviceCoordinateCache);
}
};

#include "main.moc"

int main(int argc, char **argv)
{
QApplication app(argc, argv);
MyGraphicsEllipseItem *ball = new MyGraphicsEllipseItem(QRectF(0, 0, 219, 219));

QPropertyAnimation animation(ball, "brush");
animation.setDuration(10000);

animation.setKeyValueAt(0, QBrush(QColor(255,0,0)));
animation.setKeyValueAt(0.8, QBrush(QColor(0,255,0)));
animation.setKeyValueAt(1, QBrush(QColor(0,0,255)));

QGraphicsScene *scene = new QGraphicsScene();
scene->setSceneRect(0, 0, 220, 220);
scene->addItem(ball);

QGraphicsView *view = new QGraphicsView(scene);
view->show();
animation.start();

return app.exec();
}


Название: Re: Делаем мигающий элемент блок-схемы.
Отправлено: neosapient от Октябрь 21, 2009, 11:46
Проект собирается, но в программе ничего не происходит - круг своего цвета не меняет.

Постепенно прихожу к мысле, что Animation API не умеет рассчитывать полином для QBrush, это так ?
Попутно возникает вопрос, умеет ли Animation API менять цвета в стилях QWidget-ов ?

------------------------------
Сделал два примера программы.
В первом реализовал свойство "color", через которое получается изменить цвет круга.

Код:
#include <QtCore>
#include <QtGui>

class MyGraphicsEllipseItem : public QObject, public QGraphicsEllipseItem
{
Q_OBJECT
Q_PROPERTY(QColor color READ color WRITE setColor)
public:
MyGraphicsEllipseItem(const QRectF &rect)
: QObject(), QGraphicsEllipseItem(rect)
{
setCacheMode(DeviceCoordinateCache);
}
QColor color() {
qDebug() << "color()" << brush().color().name ();
return brush().color();
}
void setColor(QColor color) {
qDebug() << "setColor()" << color.name ();
setBrush(QBrush(color));
return;
}
};

#include "main.moc"

int main(int argc, char **argv)
{
QApplication app(argc, argv);
MyGraphicsEllipseItem *ball = new MyGraphicsEllipseItem(QRectF(0, 0, 219, 219));

QPropertyAnimation animation(ball, "color");
animation.setDuration(10000);

animation.setKeyValueAt(0, QColor(255,0,0));
animation.setKeyValueAt(0.8, QColor(0,255,0));
animation.setKeyValueAt(1, QColor(0,0,255));

QGraphicsScene *scene = new QGraphicsScene();
scene->setSceneRect(0, 0, 220, 220);
scene->addItem(ball);

QGraphicsView *view = new QGraphicsView(scene);
view->show();
animation.start();

return app.exec();
}

Во втором примере, в дополнении к предыдущему посту перегрузил методы brush и setBrush. Как показал qDebug() метод setBrush не вызывается. То есть по какой то причине Animation API не воспринимает кисти.

Код:
#include <QtCore>
#include <QtGui>

class MyGraphicsEllipseItem : public QObject, public QGraphicsEllipseItem
{
Q_OBJECT
Q_PROPERTY(QBrush brush READ brush WRITE setBrush)
public:
MyGraphicsEllipseItem(const QRectF &rect)
: QObject(), QGraphicsEllipseItem(rect)
{
setCacheMode(DeviceCoordinateCache);
}
QBrush brush() const{
qDebug() << "brush()" << QGraphicsEllipseItem::brush().color().name ();
return QGraphicsEllipseItem::brush();
}
void setBrush(const QBrush & brush) {
qDebug() << "setBrush()" << brush.color().name ();
QGraphicsEllipseItem::setBrush(brush);
return;
}
};

#include "main.moc"

int main(int argc, char **argv)
{
QApplication app(argc, argv);
MyGraphicsEllipseItem *ball = new MyGraphicsEllipseItem(QRectF(0, 0, 219, 219));

QPropertyAnimation animation(ball, "brush");
animation.setDuration(10000);

animation.setKeyValueAt(0, QBrush(QColor(255,0,0)));
animation.setKeyValueAt(0.8, QBrush(QColor(0,255,0)));
animation.setKeyValueAt(1, QBrush(QColor(0,0,255)));

QGraphicsScene *scene = new QGraphicsScene();
scene->setSceneRect(0, 0, 220, 220);
scene->addItem(ball);

QGraphicsView *view = new QGraphicsView(scene);
view->show();
animation.start();

return app.exec();
}


Название: Re: Делаем мигающий элемент блок-схемы.
Отправлено: shadone от Октябрь 21, 2009, 13:11
Во втором примере, в дополнении к предыдущему посту перегрузил методы brush и setBrush. Как показал qDebug() метод setBrush не вызывается. То есть по какой то причине Animation API не воспринимает кисти.
нельзя перегрузить brush/setBrush - эти методы не виртуальные, поэтому происходить простое переопределение, и новая реализация никогда не будет вызвана т.к. вызовы происходят через указатель на базовый класс.

а по поводу собственно проблемы - скорее всего просто не хватает вызова update после изменения brush во время анимации.


Название: Re: Делаем мигающий элемент блок-схемы.
Отправлено: BRE от Октябрь 21, 2009, 13:37
а по поводу собственно проблемы - скорее всего просто не хватает вызова update после изменения brush во время анимации.
Тоже сразу так подумал, но:
Код
C++ (Qt)
void QAbstractGraphicsShapeItem::setBrush(const QBrush &brush)
{
   Q_D(QAbstractGraphicsShapeItem);
   d->brush = brush;
   update();
}
 


Название: Re: Как лучше организовать интерактивныю блок-схему.
Отправлено: SABROG от Октябрь 21, 2009, 13:54
Как я понял вот список типов, который поддерживает QVariantAnimation, чьим и является метод setKeyValueAt:

Код:
    * Int
    * Double
    * Float
    * QLine
    * QLineF
    * QPoint
    * QSize
    * QSizeF
    * QRect
    * QRectF

Чтобы добавить свои типы нужно переопределять метод:
QVariant QVariantAnimation::interpolated ( const QVariant & from, const QVariant & to, qreal progress ) const   [virtual protected]

и реализовывать свой алгоритм. Или зарегистрировать свою функцию интерполяции:
void qRegisterAnimationInterpolator ( QVariant(* ) ( const T & from, const T & to, qreal progress ) func )   [static]