The Graphics View Framework Oprogramowanie i wykorzystanie stacji roboczych Dr inż. Tomasz Olas olas@icis.pcz.pl Instytut Informatyki Teoretycznej i Stosowanej Politechnika Częstochowska The Graphics View Framework udostępnia mechanizmy umożliwiajace tworzenie obszaru (sceny) zawierajacej dwuwymiarowe obiekty graficzne. Obiekty takie moga być zarzadzane, można również przy wykorzystaniu mechanizmu detkcji kolizji określić, które obiekty nachodza na siebie. Zawiera mechanizm rozsyłania zdarzeń (zwiazanych z klawiatura i mysza) do obiektów znajdujacych się na scenie. Dzięki wykorzystaniu drzew BSP (BSP - Binary Space Partition; Drzewo podziału binarnego przestrzeni) jest możliwa detekcja kolizji oraz vizualizacja w czasie rzeczywistym scen zawierajacych nawet duża liczbę obiektów (rzędu setek tysięcy). p. 1/22 he Graphics View Framework - architektura Hierarchia klas QGraphicsItem Scena QGraphicsScene - modeluje dwuwymiarowa scenę, Widok QGraphicsView - umożliwia wizualizację zawartości sceny, Obiekt QGraphicsItem - klasa bazowa dla obiektów znajdujacych się na scenie. QGraphicsItem QAbstractGraphicsShapeItem QGraphicsEllipseItem QGraphicsPathItem QGraphicsPolygonItem QGraphicsSimpleTextItem QGraphicsRectItem QGraphicsItemGroup QGraphicsLineItem QGraphicsPixmapItem QGraphicsSvgItem QGraphicsTextItem p. 3/22
QGraphicsItem Graphics View - przykład 1 (I) Zmiana położenia obiektów klas QCanvasItem na scenie: moveby(double dx, double dy), setx(double x), sety(double y), setz(double z). Określenie kolizji: virtual bool collideswithitem ( const QGraphicsItem * other, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape ) const, virtual bool collideswithpath ( const QPainterPath & path, Qt::ItemSelectionMode mode = Qt::IntersectsItemShape ) const, QList<QGraphicsItem *> collidingitems ( Qt::ItemSelectionMode mode = Qt::IntersectsItemShape ) const, virtual bool contains ( const QPointF & point ) const. Transformacje: void rotate ( qreal angle ), void scale ( qreal sx, qreal sy ), void shear ( qreal sh, qreal sv ), void translate ( qreal dx, qreal dy ). #include <QApplication> #include <QGraphicsScene> #include <QPixmap> #include <mydisplay.h> int main(int argc, char** argv) QApplication app(argc, argv); QGraphicsScene scene(0, 0, 1000, 700); QPixmap pixmap("pic/marmur.jpg"); scene.setbackgroundbrush(qbrush(pixmap)); MyDisplay display(&scene); display.resize(1000, 700); display.show(); return app.exec(); p. 5/22 Graphics View - przykład 1 (II) Graphics View - przykład 1 (III) #include <QGraphicsView> class MyDisplay: public QGraphicsView Q_OBJECT MyDisplay(QGraphicsScene* scene, QWidget * parent = 0); protected: void mousepressevent(qmouseevent*); void mousemoveevent(qmouseevent*); void mousereleaseevent(qmouseevent*); QGraphicsItem* moving; QPoint moving_start; ; #include "mydisplay.h" #include <QMouseEvent> #include <QGraphicsEllipseItem> MyDisplay::MyDisplay(QGraphicsScene * scene, QWidget * parent): QGraphicsView(scene, parent), moving(null) QGraphicsEllipseItem* ellipse = new QGraphicsEllipseItem(0, 0, 50, 50, 0, scene ellipse->setbrush(qcolor("red")); ellipse->moveby(100,100); ellipse->setacceptdrops(true); ellipse->show(); QGraphicsTextItem* text = new QGraphicsTextItem("Test", 0, scene); text->setfont(qfont("arial", 34)); text->moveby(100,100); text->show(); p. 7/22
Graphics View - przykład 1 (IV) Graphics View - przykład 2 void MyDisplay::mousePressEvent(QMouseEvent* e) moving = scene()->itemat(maptoscene(e->pos())); if (moving) moving_start = e->pos(); void MyDisplay::mouseMoveEvent(QMouseEvent* e) if ( moving ) QPoint p = e->pos(); moving->moveby(p.x() - moving_start.x(), p.y() - moving_start.y()); moving_start = p; scene()->update(); MyDisplay::MyDisplay(QGraphicsScene * scene, QWidget * parent): QGraphicsView(scene, parent), moving(null)... QPixmap pixmap("pic/butterfly.png"); QGraphicsPixmapItem* butterfly = new QGraphicsPixmapItem(pixmap, 0, scene); butterfly->moveby(150,150); butterfly->show(); void MyDisplay::mouseReleaseEvent(QMouseEvent* e) moving = NULL; p. 9/22 Graphics View - przykład 3 (I) Graphics View - przykład 3 (II) class Butterfly: public QGraphicsPixmapItem Butterfly(const QPixmap& pixmap, QGraphicsItem * parent = 0, QGraphicsScene * scene = 0); void advance(int phase); int direction; ; void Butterfly::advance(int phase) if (phase) translate(0, direction); else QList<QGraphicsItem *> items = collidingitems(); if (items.size()) direction = -direction; Butterfly::Butterfly(const QPixmap& pixmap, QGraphicsItem * parent, QGraphicsScene * scene): QGraphicsPixmapItem(pixmap, parent, scene), direction(1) p. 11/22
Graphics View - przykład 3 (III) QMainWindow - przykład I MyDisplay::MyDisplay(QGraphicsScene * scene, QWidget * parent): QGraphicsView(scene, parent), moving(null)... QPixmap pixmap("pic/butterfly.png"); Butterfly* butterfly = new Butterfly(pixmap, 0, scene); butterfly->moveby(150,150); butterfly->show(); QTimer* timer = new QTimer(this); timer->start(30); connect(timer, SIGNAL(timeout()), scene, SLOT(advance())); #include <QMainWindow> class QTextEdit; class MyMainWindow: public QMainWindow Q_OBJECT MyMainWindow(); public slots: void FileOpen(); QTextEdit *textedit; ; p. 13/22 QMainWindow - przykład II QMainWindow - przykład III #include "fileopen.xpm" MyMainWindow::MyMainWindow() QAction * fileopenaction = new QAction( QIcon(fileopen), "Open File", this); fileopenaction->setshortcut(qkeysequence("ctrl+o")); fileopenaction->setstatustip("create a new file"); connect(fileopenaction, SIGNAL(triggered()), this, SLOT(FileOpen())); void MyMainWindow::FileOpen() QString fn = QFileDialog::getOpenFileName( this, QString::null, QString::null); if (!fn.isempty()) QFile f(fn); if (!f.open(qiodevice::readonly)) return; QMenu *filemenu = menubar()->addmenu("&file"); filemenu->addaction(fileopenaction); QToolBar *filetoolbar = addtoolbar("file"); filetoolbar->addaction(fileopenaction); textedit = new QTextEdit(this); textedit->setfocus(); setcentralwidget(textedit); statusbar()->showmessage("ready", 4000); p. 15/22 QTextStream ts(&f); textedit->settext(ts.readall()); statusbar()->showmessage("loaded document " + fn, 2000); else statusbar()->showmessage("loading aborted", 2000);
Obsługa sieci QHttp W bibliotece Qt do obsługi protokołów FTP i HTTP służa klasy QFtp i QHttp. Zostały one zbudowane w oparciu o klasę QSocket, która opakowuje gniazdka w domenie TCP. Klasa QSocket dziedziczy po klasie QSocketDevice, która mapuje wywołania funkcji bezpośrednio do (specyficznej dla danej architektury) API sieciowego. Połaczenia przy wykorzystaniu klasy QSocketDevice moga odbywać się zarówno po protokole TCP, jak również UDP. Klasa QHttp implementuje protokół HTTP po stronie klienta. Zawiera zbiór metod realizujacych operacje HTTP, w tym metody get(), post(). Polecenia HTTP wykonywane sa asynchronicznie. Powrót z metody realizujacej dana operację następuje bezpośrednio po jej wywołaniu. Polecenie jest wykonywane w tle. Po zakończeniu wykonywania polecenia sa generowane sygnały requestfinished(int id, bool error), done(bool). p. 17/22 QHttp - przykład I QHttp - przykład II #include <QApplication> #include "getfile.h" int main(int argc, char** argv) QApplication app(argc, argv); GetFile getfile; getfile.resize(210, 70); getfile.show(); app.exec(); if (getfile.isok()) execlp("acroread", "acroread", "/tmp/slides.pdf", NULL); return 0; class GetFile: public QWidget Q_OBJECT GetFile(QWidget *parent = 0); bool IsOk() const; public slots: void Done(bool); void Show(); QHttp http; QFile file; QSpinBox *number; bool ok; ; p. 19/22
QHttp - przykład III QHttp - przykład IV GetFile::GetFile(QWidget *parent): QWidget(parent), ok(false) number = new QSpinBox(this); number->setvalue(1); number->setgeometry(20, 20, 50, 30); QPushButton *show = new QPushButton("Show", this); show->setgeometry(90, 20, 100, 30); connect(show, SIGNAL(clicked()), this, SLOT(Show())); void GetFile::Done(bool error) ok =!error; file.close(); qapp->quit(); void GetFile::Show() file.setfilename("/tmp/slides.pdf"); http.sethost("icis.pcz.pl"); QString filename; filename = QString("/~olas/osr/wyklad%1.pdf").arg(number->value()); http.get(filename, &file); connect(&http, SIGNAL(done(bool)), this, SLOT(Done(bool))); p. 21/22