|
www.lissyara.su
—> статьи
—> FreeBSD
—> Programming
—> Создание программ на QT4/С++
Создание программ на QT4/С++
Автор: Fastman.
Это статья не претендует на руководство 'как правильно', это описание удобного мне окружения для написания программ при помощи кросплатформенного набора классов Trolltech QT4. Почему QT4? Не в обиду другим средствам разработки - это наиболее вменяемый тулкит который вмещает в себя как классы для создания GUI так и множество полезных классов например для работы с xml, сокетами, файлами, директориями итд...
На сегодняшний день в портах версия 4.3.1, поэтому все что будет тут написано - относится именно к этой версии QT. Для тех кому интересно уже сейчас есть возможность скачть версию QT4.4 в которой появились WEBkit(классы для разработки web-приложений) и Phonon(классы для работы с мультимедиа). А еще за что я полюбил продукт QT - так это за документацию....не поленитесь после установки сразу запустить Assistant и вы поймете о чем я говорю.
Обновляем порты и ставим QT:
fast# cd /usr/ports/devel/qt4
|
Если собираетесь работать с базами данных(mysql,postgree,sqlite etc) отметьте пункт:
[ ] SQL_PLUGINS Database connectivity plugins for QtSql
|
в этом случае соберутся плагины для работы с базами данных.
Приготовьтесь, потащится довольно много.. в итоге мы получим следующие модули:
Qt Core Module — ядро Qt
Qt GUI Module — Qt классы и модули для создания GUI
Network Module — платформо-независимые классы для работы с сокетами, TCP, FTP и DNS.
OpenGL 3D Graphics Module — OpenGL классы для 3D визуализации.
Database Module — модули для работы с SQL базами данных.
XML Module — XML парсер (SAX2 и DOM Level 2 интерфейсы)
Если все собралось без ошибок, проверим:
fast# qmake-qt4 -v
QMake version 2.01a
Using Qt version 4.3.1 in /usr/local/lib
|
Теперь добавим в .cshrc переменную QMAKESPEC которая будет указывать для какой платформы qmake-qt4 будет производить сборку, у меня это так выглядит:
fast# cat .cshrc | grep QMAKESPEC
setenv QMAKESPEC freebsd-g++
|
В принципе этого в начале достаточно чтобы писать под QT. Но очень неудобно ;) Поэтому нужно выбрать IDE(или текстовый редактор с ф-циями IDE). Это тема многих религиозных войн, я не буду навязывать какой либо редактор и советовать только его. Я для себя выбрал QDevelop. Вот примерно как это выглядит:
Это в принципе не совсем полноценная IDE, но писать код можно, автодополнение кода можно настроить, отладка приложения тоже присутствует... что еще надо? Мне этого хватает. Кто будет юзать эту IDE, вот что нужно прописать в настройках. Почему make выдает ошибку я не разбирался, работает и так.
Конечно все это интересно, но без примеров - это пустой звук. Удобность любого инструмента можно узанть только в процессе работы. Поэтому я решил привести тут небольшой 'hello world'. В кавычках - потому что никому не интересно вывести на форму этот текст... обычно хочется сразу увидеть особонности инструмента и функционал. Поэтому сейчас я приведу пример небольшого приложения с минимальным GUI которое позволит скачать на локальный диск видео с youtube.com. То есть вставив ссылку из строки браузера в приложение и нажав одну кнопку на форме - вы получите на локальном диске файл с расширением flv который можно просмотреть допустим mplayer-ом.
Придумаем минимальный дизайн нашей формы.
Окошко будет содержать строку ввода ссылки (элемент lineEdit), кнопку (элемент pushButton), и область в которой будет отображаться ход обработки нашего задания (элемент listWidget).
Окошко будем рисовать в QtDesigner, он входит в состав Qt 4.3.1, все предельно просто, этому инструменту посвящена целая глава документации. Вот скриншот того как это происходит:
После того как мы создали 'дизайн' окошка, можно наполнять смыслом наше приложение. Вообще, хочу предостеречь тех кто начинает программирование на С++, дизайн конечно дело не последнее, но лучше изначально продумать архитектру своего приложения, и поверьте если вы это сделаете правильно, то написав все приложение вы ЛЕГКО подцепите к нему дизайн. Если же функционал вашего приложения жестко зависит от визуальной части - вы что то перемудрили и сделали неправильно. Qt4 позволяет писать и консольные приложения которые не требуют наличия X-ов в вашей системе.
Прежде чем приводить код приложения поясню. Во первых, это приложение можно написать 10-30 строчками на том же перле или любом другом скриптовом языке, это факт. Это приложение можно легко переписать и сделать его более изящным и красивым. Я сделал его специально таким 'угловатым', некрасивым с точки зрения архитектуры и построения чтобы показать максимальное количество возможностей в таком маленьком приложении и чтобы вы сами могли увидеть что можно допилить до удобоваримого вида.Комментарии будут приведены минимальные, по просьбам трудящихся в дальнейшем откомментирую непонятные куски.
main.cpp
Тут мы строим главное окно приложения, и говорим что будем ловить сигнал закрытия приложения.
#include <QtGui/QApplication>
#include "youtubed.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
YouTubeD w;
w.show();
a.connect(&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
return a.exec();
}
| youtubed.h
Этот класс у нас будет отвечать за визуальную часть приложения.
#ifndef YOUTUBED_H
#define YOUTUBED_H
#include <QtGui/QMainWindow>
#include "ui_youtubed.h"
#include "Thread.h"
#include <QString>
class YouTubeD : public QMainWindow
{
Q_OBJECT
public:
YouTubeD(QWidget *parent = 0, Qt::WFlags flags = 0);
~YouTubeD();
protected:
//Не очень весело когда рабочие задания выполняются в главном потоке
//Поэтому все что не относится к отображению на форме элементов
//мы выносим в отдельный поток
//Вот и обьявляем переменную класса Thread
Thread *TubeThread;
private:
//Ui - это класс который автоматически генерируется
//из формы которую вы нарисовали
//Там обьявлены все графические элементы/виджеты которые есть на форме
//Но никто не запрещает вам самим динамически их создавать.
Ui::YouTubeDClass ui;
private slots:
//Этот слот сработает если вы жмякнете на кнопку
void on_pushButton_clicked();
//А этот когда прийдет сообщение из потока.
//Нельзя напрямую из потока дергать ф-ции графики
//на форме, поэтому один из методов - передача сигналов.
void GUImsg(QString msg);
};
#endif // YOUTUBED_H
| youtubed.cpp
#include "youtubed.h"
YouTubeD::YouTubeD(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
}
YouTubeD::~YouTubeD()
{
}
void YouTubeD::on_pushButton_clicked()
{
//Надеюсь все понятно, все до боли знакомо :)
QString cUrl("");
ui.listWidget->clear();
cUrl = ui.lineEdit->text();
//Ну по хорошему надо придумать как проверять на валидность URL
//а не проверять не пустой ли он вообще
if (cUrl.size())
{
//Если URL не пустой - выделяем память под наш поток
TubeThread = new Thread(cUrl);
//Будем ловить сигнал из нашего потока с сообщениями
connect(TubeThread, SIGNAL(msgToGUI(QString)), this, SLOT(GUImsg(QString)));
TubeThread->start();
}
else
ui.listWidget->addItem("URL empty !");
}
void YouTubeD::GUImsg(QString msg)
{
ui.listWidget->addItem(msg);
}
| Thread.h
Потоковый класс.
#ifndef THREAD_H
#define THREAD_H
#include <QThread>
#include "TubeDownload.h"
class Thread : public QThread
{
Q_OBJECT
public:
Thread(QString cUrl, QObject *parent = 0);
~Thread();
CTubeDownload *nDownld;
QString cUrl;
protected:
void run();
private slots:
void FinishProc();
signals:
void msgToGUI(QString cMesage);
};
#endif // THREAD_H
| Thread.cpp
#include "Thread.h"
Thread::Thread(QString cUrl, QObject *parent)
: QThread(parent), cUrl(cUrl)
{
}
Thread::~Thread()
{
if (nDownld != NULL)
delete nDownld;
QThread::exit();
QThread::wait();
}
void Thread::run()
{
nDownld = new CTubeDownload;
connect(this, SIGNAL(finished()), this, SLOT(FinishProc()));
connect(nDownld, SIGNAL(msgToGUI(QString)), this, SIGNAL(msgToGUI(QString)));
QString lnk = nDownld->GetDownloadLink(cUrl);
QString file = nDownld->DownloadFLV(lnk);
}
void Thread::FinishProc()
{
this->~Thread();
}
| TubeDownload.h
#pragma once
#include <QString>
#include <QFile>
#include <QProcess>
#include <QTextStream>
#include <QtDebug>
#include <QDir>
#include <QUrl>
#include <QCoreApplication>
#include <QTime>
class CTubeDownload : public QObject
{
Q_OBJECT
public:
CTubeDownload(void);
~CTubeDownload(void);
QString GetDownloadLink(const QString cUrl);
QString DownloadFLV(const QString cLink);
private:
QProcess *zProc;
QString cTmpPath;
signals:
void msgToGUI(QString cMesage);
};
| TubeDownload.cpp
Тут мы пользуемся wget-ом. Не совсем хорошо. Лучше подумать и сделать
на основе QHttp класса все. Я просто хотел показать как из своей программы
запускать другую, и как работать с файлами в QT4.
#include "TubeDownload.h"
CTubeDownload::CTubeDownload(void)
{
//Таким макаром можно сделать кроссплатформ дефайны
#ifdef Q_OS_WIN32
#define cPWget "d:\\wget.exe";
#endif
#ifdef Q_OS_FREEBSD
#define cPWget "/usr/local/bin/wget";
#endif
}
CTubeDownload::~CTubeDownload(void)
{
}
QString CTubeDownload::GetDownloadLink(const QString cUrl)
{
QString cLink(cUrl);
QString cWgetLine("");
QString cTmpFile("tmp.file");
cTmpPath = QDir::tempPath();
cTmpFile.prepend(cTmpPath);
cWgetLine = cPWget;
cWgetLine += " -O ";
cWgetLine += cTmpFile;
cWgetLine += " ";
cWgetLine += cLink;
zProc = new QProcess(this);
emit msgToGUI("Get file to parse. Please wait...");
zProc->execute(cWgetLine);
emit msgToGUI("Get file to parse - ok !");
QFile file(cTmpFile);
if(!file.open(QIODevice::ReadOnly))
return NULL;
QTextStream in(&file);
QString idFlv("");
QString FullPathURL("");
emit msgToGUI("Parse file.");
while (!in.atEnd())
{
QString line = in.readLine();
if((line.contains("fullscreenUrl", Qt::CaseInsensitive)))
{
idFlv = line.simplified();
}
}
file.close();
file.remove();
emit msgToGUI("Parse file - ok !");
emit msgToGUI("Create full link to file.");
//Грязный хак ! Не делайте так никогда :)
//Нормально распарсите полученный файл :)
idFlv = idFlv.mid(38, idFlv.length()-(38+2));
FullPathURL = "http://www.youtube.com/get_video";
FullPathURL += idFlv;
emit msgToGUI("Create full link to file - ok !");
return FullPathURL;
}
QString CTubeDownload::DownloadFLV(const QString cLink)
{
QString cDwnldFileName("");
QString cLinkFLV("");
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
cLinkFLV = cPWget;
cLinkFLV += " -O ";
cLinkFLV += QDir::homePath();
cLinkFLV += "/";
cLinkFLV += QString::number((int)(qrand()));
cLinkFLV += ".flv ";
cDwnldFileName = cLinkFLV;
cLinkFLV += cLink;
zProc = new QProcess(this);
emit msgToGUI("Download FLV file. Please wait...");
zProc->start(cLinkFLV);
zProc->waitForFinished(-1);
emit msgToGUI(cDwnldFileName);
emit msgToGUI("Download FLV file - ok !");
return cDwnldFileName;
}
| Вот готовый проект который вы можете скачать и поиграться.
YouTubeD
|
файл
|
скачан
|
размер
|
размещён
|
примечание
|
|
2133
|
26.5kb
|
2008-01-20
|
Если у вас установлен и правильно настроен QT4.3.1 то после развертывания архива необходимо сделать только make. Приложение требует установленного в системе wget.
|
|
Вот рабочий скрин:
У меня есть неплохая книга с примерами для нее отдельно. Как только починят и будет доступ к ftp - выложу.
Сссылки и ресурсы:
http://trolltech.com - Офф. сайт разработчиков.
http://www.qtcentre.org - Супер ресурс с просто офигительным форумом.
размещено: 2008-01-21,
последнее обновление: 2008-01-21,
автор: Fastman
|
|
Комментарии пользователей [17 шт.]