четвер, 28 липня 2011 р.

Використання бібліотеки Qt4 на прикладі простої OpenGL програми

У даній статті я розповім як використовувати OpenGL графіку у програмах основаних на бібліотеці Qt4 ну і власне про принципи роботи з самою бібліотекою. Я не буду ускладнювати задачу 3D графікою, обмежимося лише 2D. Створимо простеньку програмку з меню, одним пунктом у підменю та графічним віджетом. Намалюємо просту сцену з червоним квадратом на синьому фоні, квадрат можна буде рухати стрілками або мищкою та змінювати його розміри.

Для того щоб мати змогу використовувати Qt4 його потрібно спочатку встановити використовуючи менеджер пакетів. Можна також встановити чудову IDE KDevelop, але можна обійтися і найпростішим текстовим редактором.

Отже, перш за все нам потрібно створити віджет який буде відображати графіку. Робиться це не складно, у Qt взагалі дуже просто породжувати нові віджети, для цього потрібно просто створити новий клас як спадкоємець стандартного QGLWidget. Назвемо його наприклад MyGLWidget. По правилу прийнятому у Qt, кожен клас повинен описуватися своєю парою .h та .cpp файлів. Спочатку опишемо сам клас у заголовочному файлі myglwidget.h:

#ifndef MYGLWIDGET_H

#define MYGLWIDGET_H

#include

#include

class MyGLWidget : public QGLWidget

{

Q_OBJECT

public:

MyGLWidget(QWidget *parent = 0);

~MyGLWidget();

protected:

void resizeGL(int width, int height);

void paintGL();

void keyPressEvent (QKeyEvent *e);

void mousePressEvent(QMouseEvent *event);

private:

int iX, iY, iSize;

};

#endif

Тут особливу увагу потрібо звернути на використання макросу Q_OBJECT, він обробляється макропроцесором Qt і є обов'язковим для опису всіх класів віджетів. Інші методи перекривають стандартні. resizeGL - викликається при зміні розмірів віджету, paintGL - малює сцену, а keyPressEvent та mousePressEvent служать відповідно для перехвачення повідомлень від клавіатури та мишки відповідно. Самі методи реалізуються у файлі myglwidget.cpp (коментарі я додав по ходу програми):

#include "myglwidget.h"

MyGLWidget::MyGLWidget(QWidget *parent)

{

iX=125; iY=125; iSize=50; // задаємо початкові значення положення та розміру квадрату

}

void MyGLWidget::resizeGL(int width, int height)

{

if(height == 0) height = 1;

glViewport(0, 0, width, height);

glLoadIdentity();

if (width <= height) // Змінюємо систему координат таким чином щоб квадрат завжди залишався квадратом

glOrtho (0.0f, 250.0f, 0.0f, 250.0f*height/width, 1.0, -1.0);

else

glOrtho (0.0f, 250.0f*width/height, 0.0f, 250.0f, 1.0, -1.0);

}

void MyGLWidget::paintGL()

{

glClearColor(0.0f, 0.0f, 1.0f, 1.0f); // Задаємо синій колір для фону

glClear(GL_COLOR_BUFFER_BIT); // Очищуємо вікно

glColor3f(1.0f, 0.0f, 0.0f); // Обираємо червоний колір

glRectf(iX-iSize/2, iY+iSize/2, iX+iSize/2, iY-iSize/2); // Малюємо квадрат

glFlush(); // Виводимо зображення на екран

}

void MyGLWidget::keyPressEvent(QKeyEvent *e)

{

switch(e->key()) // Аналізуємо яку клавішу натиснено

{

case Qt::Key_Up: ++iY; break;

case Qt::Key_Down: --iY; break;

case Qt::Key_Left: --iX; break;

case Qt::Key_Right: ++iX; break;

case Qt::Key_Z: ++iSize; break;

case Qt::Key_X: --iSize; break;

default: QWidget::keyPressEvent(e); // Передаємо керування батківському методу

}

updateGL(); // Оновлюємо зображення

}

void MyGLWidget::mousePressEvent(QMouseEvent *event)

{

if (event->buttons() & Qt::LeftButton) { // Перевіряємо чи натиснуто ліву кнопку мишки

iX=event->x(); // Змінюємо положення квадрату

iY=height()-event->y(); // Зверніть увагу, у системах координат OpenGL та Qt вісь Y направлена у протилежні сторони

updateGL(); // Оновлюємо зображення

}

}

MyGLWidget::~MyGLWidget()

{ } // Деструктор залишаємо пустим

Все, ми створили новий графічний віджет. Тепер, нам потрібно створити клас основного вікна. Для цього потрібно створити спадкоємця для QMainWindow. Нехай новий клас буде називатися qt4gl, тоді файл qt4gl.h буде мати наступний вигляд:

#ifndef QT4GL_H

#define QT4GL_H

#include

#include

class QAction;

class QMenu;

class QTextEdit;

class MyGLWidget;

class qt4gl:public QMainWindow

{

Q_OBJECT

public:

qt4gl();

~qt4gl();

private:

void createActions();

void createMenus();

void readSettings();

MyGLWidget *glCanvas;

QMenu *fileMenu;

QAction *exitAct;

};

#endif

Ну і відповідно реалізація у файлі qt4gl.cpp:

#include

#include "qt4gl.h"

#include "myglwidget.h"

#include

qt4gl::qt4gl()

{

glCanvas = new MyGLWidget; // Створюємо екземпляр віджету MyGLWidget

setCentralWidget(glCanvas); // Робимо його центральним віджетом у вікні

createActions(); // Ініціалізуємо набір екшенів

createMenus(); // Створюємо меню

glCanvas->setFocus(); // передаємо активний фокус нашому графічному віджету

}

void qt4gl::createActions()

{

exitAct = new QAction(tr("E&xit"), this); // Створюємо екшен для реалізації виходу з програми

exitAct->setShortcut(tr("Esc")); // Задаємо коротку клавішу

exitAct->setStatusTip(tr("Exit the application")); // Задаємо підказку

connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); // Задаємо зв'язку сигнал-слот для виконання команди

}

void qt4gl::createMenus()

{

fileMenu = menuBar()->addMenu(tr("&File")); // Додаємо підменю у головне меню

fileMenu->addAction(exitAct); // Додаємо пункт меню вказавши відповідний екшен

}

qt4gl::~qt4gl()

{ }

Готово, основне вікно тепер створено. Для не знайомих з філософією Qt може бути незвичним наступний рядок:

connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));

Сигналом у поняттях Qt називається подія яка виникає внаслідок тих або інших дій користувача, у даному випадку вибору пункта меню (triggered), але таких стандартних сигналів є досить багато. Слот - це метод який будучи зв'язаним з кокретним сигналом автоматично викликається при настанні тієї чи іншої події. Це основне з положень на якому базується Qt, у спеціальній літературі дане питання описано більш докладно.

Ну і на завершення створимо основний файл програми (main.cpp):

#include

#include "qt4gl.h"

int main(int argc, char *argv[])

{

QApplication app(argc, argv); // Ініціалізуємо програму

qt4gl * mw = new qt4gl(); // Створюємо основне вікно

mw->resize(250,250); // Задаємо розміри центрального віджета

mw->setWindowTitle(QObject::tr("OpenGL + Qt4")); // Вказуємо заголовок вікна

mw->show(); // Виводимо вікно на екран

return app.exec(); // Запускаємо головний цикл програми, return тут використовується для повернення результату виконання програми операційній системі, для *nix вимагається.

}

Ну от. Тепер залишається лише все це зкомпілювати. Для цього створюємо папку qt4gl, копіюємо туди всі наші файли і запускаємо команду:

qmake -project

У папці з програмою з'явиться файл проекта qt4gl.pro. Відкриємо його у будь-якому текстовому редакторі і додамо у його кінець наступний рядок (ця обція необхідна для роботи з OpenGL):

QT += opengl

Після збереження виконуємо команду:

qmake qt4gl.pro

Після завершення виконання даної програми препроцесор Qt створить Makefile під конкретну платформу. Тепер вже можна запускати безпосередньо компіляцію програми:

make

Якщо код набрано без помилок, то по завершенню компіляції у цій же папці з'явиться файл qt4gl. Це і є готовий бінарний файл з програмою. Запустимо його:

./qt4gl

Результатом буде наступне:

Квадрат можна рухати стрілками на клавіатурі або просто клацнувши у будь-якому місці мишкою, клавішами Z та X можна змінювати розмір квадрату. Щоб закрити вікно можна обрати у меню File пункт Exit, або просто натиснути Esc. Зміна розмірів вікна призведе до автоматичного масштабування і квадрату. Тобто все працює так як і було задумано.

На завершення, хочу порекомендувати книжку C++ GUI Programming with Qt 4 By Jasmin Blanchette, Mark Summerfield. Дуже легко читається і у той же час все докладно пояснюється.

41 коментар:

  1. Hey there I am so happy I found your webpage, I really found you by error, while I was
    browsing on Yahoo for something else, Anyways I am here now and would just
    like to say kudos for a tremendous post and a all round thrilling blog (I also
    love the theme/design), I don’t have time to look over it all
    at the moment but I have saved it and also added in your RSS feeds,
    so when I have time I will be back to read a lot more, Please do keep up
    the superb jo.
    Look into my website - best online casinohttp://

    ВідповістиВидалити
  2. I tend not to comment, but I read a few of the remarks on this page "Використання бібліотеки Qt4 на прикладі простої OpenGL програми".
    I actually do have 2 questions for you if it's okay. Could it be simply me or do a few of these responses appear as if they are coming from brain dead people? :-P And, if you are writing on additional online sites, I'd
    like to keep up with anything new you have to post. Could you list of every
    one of your social community sites like your twitter feed, Facebook page
    or linkedin profile?

    My website; How To Detox Your Body

    ВідповістиВидалити
  3. Hi! Someone in my Ϻyѕpacе group shаreԁ thiѕ site with us so I came to check it out.
    I'm definitely enjoying the information. I'm bοok-marking and will bе tweeting this to my followers!
    Fantaѕtic blog and fantastic style and ԁеsign.


    Also visit my web blog: how to become a diagnostic medical sonography

    ВідповістиВидалити
  4. Hi! I know this is kinda off topic nevertheless I'd figured I'd ask.
    Would you be interested in exchanging links or maybe guest writing
    a blog post or vice-versa? My website discusses a lot of the same topics as
    yours and I feel we could greatly benefit from each other. If
    you happen to be interested feel free to send me an e-mail.
    I look forward to hearing from you! Excellent blog by the way!



    Review my web blog :: how to lose Belly fat

    ВідповістиВидалити
  5. Greetings! I've been reading your site for some time now and finally got the courage to go ahead and give you a shout out from Lubbock Tx! Just wanted to tell you keep up the fantastic job!

    My web page :: World Of Tanks Hack

    ВідповістиВидалити
  6. Why users still use to read news papers when in this technological globe
    everything is presented on net?

    Here is my web page - tattoo removal cream reviews

    ВідповістиВидалити
  7. Hey I know this is off topic but I was wondering if you
    knew of any widgets I could add to my blog that automatically tweet my newest twitter
    updates. I've been looking for a plug-in like this for quite some time and was hoping maybe you would have some experience with something like this. Please let me know if you run into anything. I truly enjoy reading your blog and I look forward to your new updates.

    Also visit my web blog ... World Of Tanks Hack

    ВідповістиВидалити
  8. If some one wishes to be updated with most recent technologies after
    that he must be pay a quick visit this web site and be up to date all the time.



    Also visit my page; microsoft points

    ВідповістиВидалити
  9. Hi it's me, I am also visiting this web site regularly, this site is in fact good and the users are genuinely sharing good thoughts.

    Have a look at my blog :: Http://www.diaperrashhomeremedies.Com

    ВідповістиВидалити
  10. An outstanding share! I've just forwarded this onto a coworker who has been conducting a little research on this. And he in fact bought me dinner because I discovered it for him... lol. So let me reword this.... Thanks for the meal!! But yeah, thanx for spending time to talk about this matter here on your internet site.

    Feel free to surf to my web page :: Unknown

    ВідповістиВидалити
  11. Hello, the whole thing is going sound here and ofcourse every one is sharing facts, that's genuinely good, keep up writing.

    Feel free to surf to my website :: Unknown

    ВідповістиВидалити
  12. I'm truly enjoying the design and layout of your site. It's a very easy on the eyes which makes it much more enjoyable
    for me to come here and visit more often. Did you hire out a developer to create
    your theme? Fantastic work!

    Here is my webpage ... Unknown

    ВідповістиВидалити
  13. At this time it looks like Movable Type is the preferred blogging platform available right now.

    (from what I've read) Is that what you're using on your blog?


    Here is my web blog Http://Www.Journalhome.Com/

    ВідповістиВидалити
  14. Thanks for a marvelous posting! I definitely enjoyed reading it, you
    might be a great author.I will be sure to bookmark your blog and may come back someday.
    I want to encourage that you continue your great posts, have a
    nice day!

    my website; Unknown

    ВідповістиВидалити
  15. Hi i am kavin, its my first time to commenting anywhere, when i
    read this article i thought i could also make comment due
    to this good post.

    my webpage: Unknown

    ВідповістиВидалити
  16. I am sure this post has touched all the internet viewers, its really
    really pleasant paragraph on building up new web site.

    Feel free to visit my web site ... get rid of stretch marks

    ВідповістиВидалити
  17. Its like you read my mind! You appear to know a lot about this, like you wrote the book in it or
    something. I think that you could do with a few pics to
    drive the message home a little bit, but other than that, this is wonderful blog.
    An excellent read. I'll certainly be back.

    My web-site; Mon Jervois

    ВідповістиВидалити
  18. Good day! I know this is somewhat off topic but I was wondering if you knew where
    I could get a captcha plugin for my comment form?
    I'm using the same blog platform as yours and I'm having problems finding one?
    Thanks a lot!

    Here is my webpage :: Diaper Rash Remedies

    ВідповістиВидалити
  19. Hi, I want to subscribe for this weblog to take most recent updates, therefore where can i do it please help.



    Review my web blog Unknown

    ВідповістиВидалити
  20. Excellent web site you have got here.. It's hard to find good quality writing like yours these days. I truly appreciate people like you! Take care!!

    Look into my web page: monicajhtbirz.bravesites.com

    ВідповістиВидалити
  21. I just could not go away your web site prior to suggesting that I really loved the
    standard information an individual provide for your visitors?
    Is going to be again regularly in order to investigate cross-check new posts

    Here is my webpage ... jailbreak Ps3 3.6

    ВідповістиВидалити
  22. Excellent web site you've got here.. It's hard
    to find quality writing like yours these days. I honestly appreciate people
    like you! Take care!!

    Feel free to visit my web site ... Recycling Facts

    ВідповістиВидалити
  23. After looking at a few of the blog articles on your site,
    I really appreciate your technique of writing a blog.
    I book marked it to my bookmark site list and will be checking back soon.

    Take a look at my website as well and let me know what
    you think.

    Here is my page ... Psn Code Generator

    ВідповістиВидалити
  24. I read this article fully on the topic of the resemblance of
    most up-to-date and earlier technologies, it's awesome article.

    My site coconut oil for hair

    ВідповістиВидалити
  25. When I initially commented I seem to have clicked the -Notify
    me when new comments are added- checkbox and from now on whenever
    a comment is added I receive four emails with the exact same comment.
    Is there a means you are able to remove me from that service?

    Kudos!

    Also visit my weblog permanent hair straightening

    ВідповістиВидалити
  26. I like the helpful info you provide in your articles.
    I will bookmark your blog and check again here regularly.
    I'm quite sure I will learn a lot of new stuff right here! Best of luck for the next!

    my webpage http://www.comunedicogliate.it/modules.php?name=your_account&op=userinfo&username=isabelapp

    ВідповістиВидалити
  27. Hi, I wish for to subscribe for this webpage to take most up-to-date updates, thus
    where can i do it please help out.

    My webpage Eco Sanctuary

    ВідповістиВидалити
  28. What's up to every body, it's my first pay a visit of this weblog; this
    blog consists of amazing and genuinely good stuff in support of readers.



    Also visit my web-site; playstation 3 Jailbreak

    ВідповістиВидалити
  29. Pretty great post. I simply stumbled upon your blog and wished to mention that I have really loved surfing around
    your blog posts. In any case I will be subscribing to your feed and I hope you write
    once more soon!

    my homepage; The Interlace

    ВідповістиВидалити
  30. Great beat ! I wish to apprentice while you amend your website,
    how could i subscribe for a blog web site? The account helped me
    a acceptable deal. I had been a little bit acquainted of this your broadcast
    offered bright clear concept

    Feel free to visit my web page - league of legends hack

    ВідповістиВидалити
  31. Hi there to every , as I am really eager of reading this webpage's post to be updated daily. It consists of nice material.

    Feel free to surf to my web-site; World Of Tanks Hack

    ВідповістиВидалити
  32. Every weekend i used to go to see this website, for the
    reason that i want enjoyment, since this this
    website conations actually pleasant funny stuff too.


    My weblog ps3 Usb jailbreak

    ВідповістиВидалити
  33. My partner and I absolutely love your blog and find almost
    all of your post's to be exactly what I'm looking for.
    Does one offer guest writers to write content for yourself?
    I wouldn't mind producing a post or elaborating on most of the subjects you write in relation to here. Again, awesome website!

    Also visit my homepage :: ps Jailbreak

    ВідповістиВидалити
  34. Hmm is anyone else experiencing problems with the pictures on this blog loading?
    I'm trying to figure out if its a problem on my end or if it's the blog.
    Any feedback would be greatly appreciated.

    Here is my web page :: Generateur de Code PSN

    ВідповістиВидалити
  35. My partner and I stumbled over here different web page and thought I might check things out.
    I like what I see so now i am following you. Look forward to finding out about your web page again.


    Also visit my homepage - Psn Code Generator

    ВідповістиВидалити
  36. Thanks for any other informative website. Where else could
    I am getting that type of info written in such a perfect approach?
    I have a venture that I am simply now operating on,
    and I have been at the glance out for such info.

    Feel free to visit my web site; Green coffee bean extract review

    ВідповістиВидалити
  37. Wonderful article! We will be linking to this great post on our website.

    Keep up the great writing.

    Here is my weblog: laungery **

    ВідповістиВидалити
  38. Wow! This blog looks just like my old one! It's on a entirely different subject but it has pretty much the same layout and design. Wonderful choice of colors!

    Feel free to visit my blog Minecraft crack

    ВідповістиВидалити
  39. Wow, marvelous blog format! How lengthy have you ever been blogging for?
    you made blogging glance easy. The total glance of your website is magnificent, as neatly as the content!


    Also visit my webpage - Jailbreak Ps3 3.60

    ВідповістиВидалити
  40. Pretty section of content. I just stumbled upon your weblog and in accession capital to assert
    that I get actually enjoyed account your blog posts.
    Anyway I will be subscribing to your feeds and even I achievement you access consistently
    fast.

    My site; code Psn Gratuit

    ВідповістиВидалити
  41. I drop a leave a response whenever I like a post on a website or if I have something
    to valuable to contribute to the conversation. Usually it is caused by the sincerness displayed in the article I browsed.
    And after this article "Використання бібліотеки Qt4 на прикладі простої OpenGL програми".
    I was actually excited enough to drop a comment :
    -) I do have a couple of questions for you
    if you do not mind. Could it be simply me or do some of the
    responses come across like they are written by brain dead individuals?
    :-P And, if you are writing on other social sites, I would like to follow you.
    Would you list the complete urls of your public sites like your Facebook page, twitter
    feed, or linkedin profile?

    Look at my homepage; get targeted twitter followers

    ВідповістиВидалити