显示标签为“QT”的博文。显示所有博文
显示标签为“QT”的博文。显示所有博文

2014年9月11日星期四

使用QNetworkAccessManager下载文件的一个问题

今天发现一个问题,使用Qt的QNetworkAccessManager进行下载,将其放入一个QPushButton的clicked()的slots,但是无法正确执行下载文件,想了半天,还是没有搞明白,最后在stackoverflow在找到这个问题的解决方法,才明白,因为QNetworkAccessManager是非同步的,它需要一个event loop去开始下载,而我们执行clicked()这个slots,它会给一个control back给event loop,但是QNetworkAccessManager以及被销毁了,没有时间去做QNetworkAccessManager的下载文件。

解决方法:如果加入一个QMessageBox,这样就会启动另一个event loop在这个slot里面,这样QNetworkAccessManager就会有机会完成下载文件这个工作。

链接:
http://stackoverflow.com/questions/7870017/how-can-i-download-file-from-the-internet-in-qt

2014年8月19日星期二

Qt Webkit 加入新的plugin路径

在Qt中使用QWebView播放flash文档(swf格式),需要加入NPSWF32.dll这个plugin,如果使用plugin要使用下面代码,去允许使用plugin:

QWebSettings *settings = QWebSettings::globalSettings();

settings->setAttribute (QWebSettings::PluginsEnabled, true);

但是如果还是无法显示flash文档,其实原因是Qt无法找到正确的plugin路径,需要使用类似以下代码,告诉Qt正确的含有NPSWF32.dll的plugin路径:

QString path  = QDir::currentPath() + "/webplugins";

qputenv("QTWEBKIT_PLUGIN_PATH", path.toLocal8Bit());

2013年11月28日星期四

转换QImage到FFmpeg的internal YUV format

今天正巧有时间,在家里修改并整理一下我3年前写的视频播放和储存代码。FFmpeg更新非常快,突然发现我还在使用2011年09月23日的FFmpeg版本。最新版本已经到了2.1.1(http://ffmpeg.zeranoe.com/builds/win32/dev/),刚刚下载了,试着编译以前写的代码,发现很多API都变了,无法编译了,懒得再进行调整了,放弃使用新版本了,新的特性暂时用不到。我将2011年09月23日的FFmpeg版本作为项目的标准lib,打包上传到服务器上,还有SVN里。

刚刚在修改“转换QImage到FFmpeg的internal YUV format的方法”,这个方法是从QtFFmpegWrapper项目抄来的,https://code.google.com/p/qtffmpegwrapper/。我发现,我刚刚写的新代码中使用的是QImage::Format_RGB888,如果直接使用这个方法转换的frame就会不正确,是黑白的而且尺寸也不对,想了一下,其实只需要将ffmpeg::sws_getCachedContext这个API里的Source PixelFormat 改成PIX_FMT_RGB24就行了,简单而言只要注意将QImage的PixelFormat和AVFrame的PixelFormat正确对应就行了,具体代码如下面所示。

void convertImage_sws(const QImage &img)
{
   // Check if the image matches the size
   if(img.width() != getWidth() || img.height() != getHeight())
   {
      printf("Wrong image size!\n");
      return false;
   }
   if(img.format() != QImage::Format_RGB32 && img.format() != QImage::Format_ARGB32 && img.format() != QImage::Format_RGB888)    
   {
      printf("Wrong image format\n");
      return false;
   }

   //img_convert_ctx = ffmpeg::sws_getCachedContext(img_convert_ctx, getWidth(), getHeight(),
      // ffmpeg::PIX_FMT_BGRA, getWidth(),getHeight(), ffmpeg::PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);

   img_convert_ctx = ffmpeg::sws_getCachedContext(img_convert_ctx, getWidth(), getHeight(),  ffmpeg::PIX_FMT_RGB24,  getWidth(), getHeight(), ffmpeg::PIX_FMT_YUV420P,  SWS_BICUBIC,  NULL,  NULL,  NULL);

   if (img_convert_ctx == NULL)
   {
      printf("Cannot initialize the conversion context\n");
      return false;
   }

   uint8_t *srcplanes[3];
   srcplanes[0] = (uint8_t*)img.bits();
   srcplanes[1] = 0;
   srcplanes[2] = 0;

   int srcstride[3];
   srcstride[0] = img.bytesPerLine();
   srcstride[1] = 0;
   srcstride[2] = 0;

   ffmpeg::sws_scale(img_convert_ctx, srcplanes, srcstride, 0, getHeight(), ppicture->data, ppicture->linesize);

   return true;
}

2011年2月12日星期六

将Qt Application Project改成Qt Library Project

很久没有写一些关于Qt的东西,今天介绍一个小方法将Qt Application Project 改成Qt Library Project。
换句话来说,如果原来使用的是Qt项目,生成exe,后来想要将这个项目生成DLL,那么简单的改变方法如下(在VS2008中):

在project的设置里(没有什么特别的步骤,唯一请注意第三部):

1) 定义一个macro 对于Qt,DLL export,写一个头文件(但是也是可以直接使用Q_DECL_EXPORT,类似和Qt的DLL project自动生成头文件一样。

#ifndef MYGLOBAL_H
#define MYGLOBAL_H 

#include <QtCore/qglobal.h> 

#ifdef MYLIB_LIB
# define MY_EXPORT Q_DECL_EXPORT
#else
# define MY_EXPORT Q_DECL_IMPORT
10 #endif 
11
12 #endif // MYGLOBAL_H 

2) 将Project的Configuration Tpye改成Dynamic Library (.dll)

3) 修改Prprocessor Definitions设定:
MYLIB_LIB
QT_DLL

4) linker-->Ouput File 改成生成.dll

5) 在我们想要export的class加入上面写的头文件
和一般dll export类似,只是我们这里使用的是我们定义的export的macro

1 class MY_EXPORT MainWindow : public QMainWindow 

 

附注
如果只是简单的使用__declspec(dllexport) ,而不是使用Qt的export DLL的macro,如果使用生成的DLL会出现类似这样的错误。
error LNK2001: unresolved external symbol "public: static struct QMetaObject const XXX::staticMetaObject"
非常简单来说,Qt的object比较特殊,不能直接通过常用的__declspec(dllexport)进行export。

2010年6月15日星期二

使用Qt Designer进行QLayout设定

用Qt开发GUI的朋友一定对QLayout类很熟悉
我们常常使用QGridLayout,QFormLayout,QBoxLayout,QHBoxLayout,QVBoxLayout 
但是完全用写代码的方式设计GUI,往往是挺麻烦的,至少对我而言
还好我们有Qt Designer

今天,非常简单地谈谈如何使用Qt Designer进行Layout
这里举一简单的例子,我们使用Qt Designer进行Layout做一个视频播放程序的非常简单的用户操作界面

在Qt Designer中Layout可以从Widget Box中选择
也可以从Menu Bar中选择
例如下图

Qt_Designer_1_hanyionet

圈选我们需要进行Layout的Widget例如一些已经设定好的PushButton,Slider等等
然后点击我们进行Layout的类型,例如这里使用了QGridLayout
完成后在Object Inspector中可以看到我们的选择
在Property Editor里可以看到我们的Layout的Stretch等等变量
我们也可以继续手动进行一些微调,例如水平和垂直spacing等等
具体如下图所示

Qt_Designer_2_hanyionet

接下来进行一些类似的QHBoxLayout将一些Label放入其中,和上面的操作类似

最后将QHBoxLayout和QGridLayout整体再放入QWidget的Vertical Layout里
现在大功告成,看吧,实在非常简单吧

可以看到我们完成的一个视频播放程序的非常简单的用户操作界面
如下图所示,点击下面的图可以看大图

Qt_Designer_3_hanyionet

Qt_Designer_hanyionet

在做一些非常简单的演示程序的时候,如果采用Qt Designer进行Layout,常常会节省很多时间,提高编码效率

Enjoy!

2010年2月20日星期六

Qt 自定义 Combo Box

这星期效率还不错,延续了上周的状态,写了非常多的代码,但是大部分都是低复杂度的”简单代码”,写了一些Gui。和一些同事不一样,我很喜欢写Gui,因为写完马上就可以看到成果,很有成就感,而且用Qt写Gui感觉就像堆积木,很简单,只要找到自己需要的API,我个人非常喜欢Qt风格的C++的应用程序接口,很清晰且简单,相当直觉化

customize_combo_box_qt这里和大家很简单谈一些我最近用Qt写Gui的发现的好玩特性,也许Qt的标准控件已经不能满足你了,其实,我们同样可以很容易地进行自定义控件,这里使用Combo Box作为例子。

以下代码会构建出我们自定义的Combo Box,如附图所示,这里使用了Qt Style Sheet

 

 

// set some self defined colors
QColor royalBlue;
QColor orange;
royalBlue.setRgb(65, 105, 225);
orange.setRgb(255, 165, 000);

// set default color
myComboBox->setStyleSheet("* { background-color: rgb(65, 105, 225) }");

myComboBox->insertItem(0, "blue");
myComboBox->setItemData(0, royalBlue, Qt::BackgroundRole);

myComboBox->insertItem(1, "red");
myComboBox->setItemData(1, Qt::red, Qt::BackgroundRole);

myComboBox->insertItem(2, "green");
myComboBox->setItemData(2, Qt::green, Qt::BackgroundRole);

myComboBox->insertItem(3, "yellow");
myComboBox->setItemData(3, Qt::yellow, Qt::BackgroundRole);

myComboBox->insertItem(4, "orange");
myComboBox->setItemData(4, orange, Qt::BackgroundRole);

myComboBox->insertItem(5, "cyan");
myComboBox->setItemData(5, Qt::cyan, Qt::BackgroundRole);

myComboBox->insertItem(6, "purple");
myComboBox->setItemData(6, Qt::magenta, Qt::BackgroundRole);

 

 

也许还不过瘾,我们还可以通过QPalette来自定义我们的Combo Box,以下是一个简单例子。

 QPalette myPalette = myComboBox->palette();

 // outline around the menu
 myPalette.setColor(QPalette::Window, Qt::red);    
 myPalette.setColor(QPalette::WindowText, Qt::white);

 // customize myComboBox button
 myPalette.setColor(QPalette::Button, Qt::darkCyan);  
 myPalette.setColor(QPalette::ButtonText, Qt::white);
 
 // customize myComboBox menu
 myPalette.setColor(QPalette::Base, Qt::darkCyan);  
 myPalette.setColor(QPalette::Text, Qt::white);

 // customize highlight button and menu
 myPalette.setColor(QPalette::Highlight, Qt::blue);   
 myPalette.setColor(QPalette::HighlightedText, Qt::red);
 
 // customize the disabled color
 myPalette.setColor(QPalette::Disabled, QPalette::Button, Qt::gray);
 myPalette.setColor(QPalette::Disabled, QPalette::ButtonText, Qt::lightGray);
 
 myComboBox->setPalette(myPalette);

2009年11月22日星期日

除了编GUI,Qt还可以做很多事

昨天和学长一起讨论一个旧的项目,他看到我的project里大量使用了Qt的库,说Qt不是做GUI的吗,在编一些非GUI的东西你用它们干嘛(看来这是很多人的既定观点,真的需要改变一下),我说Qt不仅只是可以做GUI还可以完成很多东西,并且很强大,绝对不会比你常用的库弱。整个项目使用Qt的库还可以在一定程度上统一编程风格,并提高代码质量和减少维护开销,Qt库也提供很好的线上资源,很方便查阅。我这里举三个很简单的例子,说明Qt库的一些其他特性。

信号和槽

正如CObject是大多数MFC类的根类或基类,QObject是Qt的基类。先在我们的类继承QObject,并在类声明中使用的Q_OBJECT宏,我们就可以使用QObject信号和槽的强大的机制。
QObject信号和槽即简单又好用,现在举一个简单的例子,在例子中使用QTime和QObject信号和槽,每100微妙对象间自动进行一次接口的数据交换。

/* myclass.h */
#include <QObject> 
#include <QTime> 

class MyClass : public QObject { 
    Q_OBJECT 
public: 
    MyClass(); 
    int data_in; 
    int data_out; 

private slots: 
    void dataExchangePipe(); 

private: 
    AnotherClass anotherclass; 
    QTimer *poller; 
};
 
 
/* myclass.cpp */
MyClass::MyClass() { 
    object = new AnotherClass; 
    poller = new QTimer(this); 
    connect(poller, SIGNAL(timeout()), this, SLOT(dataExchangePipe())); 
    poller->start(100); // the time to poller 
}
 
void MyClass::dataExchangePipe() { 
    data_in = object->data_out; 
    object->data_in = data_out; 
}

容器,迭代器

还在使用STL容器吗,也许Qt也是一个很好的选择,Qt提供了QVector<T>, QLinkedList<T>,QList<T>QMap<K,T> and QHash<K,T>容器。Qt提供对容器的两种风格的迭代:Java风格的迭代器和STL风格迭代器

Java风格(非常简单,Qt官网上的一个例子)

QList<QString> list; 
list << "A" << "B" << "C" << "D"; 
QListIterator<QString> i(list); 
while (i.hasNext()) 
    qDebug() << i.next();


STL风格(比较powerful,每一个sequential container class C<T>都有两个 STL-style 迭代器类型: C<T>::iterator 和 C<T>::const_iterator,以下是Qt官网上的例子)

QList<QString> list;  
list << "A" << "B" << "C" << "D";  
QList<QString>::iterator i = list.end(); 
while (i != list.begin()) { 
    --i;
    *i = (*i).toLower(); 
}

多线程

Qt的QThread很类似C++Boost线程库。使用起来也非常容易,例如:

建thread:

#include <QThread> 
class MyThread : public QThread { 
  public: void run();  
}; 

void MyThread::run() { 
... 
... 
}

使用thread,很简单:

先声明对象,MyThread *mythread = new MyThread;

启动: mythread->start();

终止: mythread->terminate();

对线程的同步,Qt也提供了QMutex;我们可以声明QMutex mutex;然后使用mutex.lock();和mutex.unlock();进行线程同步。

更多有用的特性请查阅:http://doc.trolltech.com/4.5/index.html

2008年12月27日星期六

setCentralWidget使用嵌入SDL的Qt Widget?

以前讨论了SDL嵌入Qt Widget, 比较规范的方法是,我在以前的文章里已经提过了:  

char variable[64]; 
_snprintf(variable, sizeof(variable), "SDL_WINDOWID=0x%lx", winId()); 
SDL_putenv(variable); 

这里只使用了三行程序,很简单,唯一要注意的一点:不要使用effectiveWinId (),而是要使用winId ()。
现在我们要使用这个已经嵌入SDL的Qt Widget, 我做了两个测试:


测试1:在MainWindow中使用setCentralWidget

SDLVideo *sdlvideo = new SDLVideo; 
setCentralWidget(sdlvideo); 


结果:无法成为MainWindow的CentralWidget,程序执行一下就立刻结束。测试2:在MainWindow中使用QDockWidget 

SDLVideo *SDLVideo_dock = new SDLVideo; 
QDockWidget *dock_a = new QDockWidget(tr("Media Player of ... ..."), this); 
dock_a->setWidget(SDLVideo_dock); 
//addDockWidget(Qt::LeftDockWidgetArea, dock_a); 
viewMenu->addAction(dock_a->toggleViewAction()); 

结果:和预料的一样,也无法成为MainWindow的QDockWidget,程序执行一下就立刻结束。
结论:经过两个测试证明,SDL嵌入Qt Widget,在一定程度上不能和一般的Qt Widget一样工作,虽然现在它也是Widget但是它只是一个“类Qt Widget”,一定程度上也是一个SDL app,它只是嵌入一个Qt Widget。原因是winid的返回值的问题,在windows下会有点问题,在linux下以上的程序应该就没有问题。

2008年12月26日星期五

用Qprocess调用外部mplayer.exe

最简单的使用Qprocess调用外部mplayer.exe的方法,以下是一个简单的例子:

void MainWindow::showMplayer() { 
    const QString mplayerPath("D:/Download/MPlayer-1.0rc2/MPlayer-1.0rc2/mplayer.exe"); 
    QStringList args; 
    args << "D:/Documents and Settings/Project/release/test.avi"; 
    QProcess *myProcess = new QProcess; 
    myProcess->start(mplayerPath, args);
}

接下来,比较复杂,我不仅调用外部mplayer.exe的方法,而且还要将播放窗口放到Qt Widget。这时必须使用mplayer 的-wid参数,这可以将mplayer输出流重定向的指定的窗体(这里就是我们所要的Qt Widget)。同时我们也可以设定一些mplayer的参数。注意:QWidget::winId() returns an HWND not an int.所以要使用类似QString::number(reinterpret_cast<qlonglong>(wd->winId()))的语句。还有一点,mplayer的configure里的GUI必须disable,不然也无法将mplayer输出流定向到Qt Widget上。以下是一个简化的例子:

void MainWindow::showMplayer() { 
    QWidget *wd = new QWidget(this);
    const QString mplayerPath("D:/Download/MPlayer-1.0rc2/MPlayer-1.0rc2/mplayer.exe"); 
    QStringList args; 
    args << " -wid" << QString::number(reinterpret_cast<qlonglong>(wd->winId())); 
    args <<" D:/Documents and Settings/Project/release/test.avi"; 
    QProcess *myProcess = new QProcess(this); 
    myProcess->start(mplayerPath,args); 
    wd->show(); 
}

2008年12月15日星期一

gcc/g++

gcc/g++在执行编译工作-->总共需要4步
1.预处理,生成.i的文件[预处理器cpp]
2.将预处理后的文件不转换成汇编语言,生成文件.s[编译器egcs]
3.有汇编变为目标代码(机器代码)生成.o的文件[汇编器as]
4.连接目标代码,生成可执行程序[链接器ld]

2008年12月4日星期四

一些小问题

int snprintf(char *restrict buf, size_t n, const char * restrict format, ...);

函数说明:最多从源串中拷贝 n 1 个字符到目标串中,然后再在后面加一个 0 。所以如果目标串的大小为 n 的话,将不会溢出。函数返回值:若成功则返回欲写入的字符串长度,若出错则返回负值。

_snprintf(variable, sizeof(variable), "SDL_WINDOWID=0x%lx", winId());
//snprintf(variable, sizeof(variable), "SDL_WINDOWID=0x%lx", winId());
snprintf函数并不是标准c/c++中规定的函数,但是在许多编译器中,厂商提供了其实现的版本。
在gcc中,该函数名称就snprintf,而在VC中称为_snprintf。但是我在编译的过程中,使用_snprintf就不会出现warning,若使用snprintf则会出现warning。

qmake 不会处理.cpp文件里的Q_OBJECT,所以,如果在.cpp文件中有它的话,也会产生undefined reference to vtable for "xxx::xxx". 这时,需要先用moc xxxx.cpp生成相应的moc文件,再包含到.cpp里面去,才能解决这个问题.
要解决上面的问题
如果分开, 可能就没问题, 包括 h和 cpp 分开。在你main.cpp 最后加一行 #include "main.moc" from:http://blog.donews.com/netexe/archive/2006/02/09/720544.aspx

from: http://lists.mplayerhq.hu/pipermail/ffmpeg-user/2007-March/007669.html
The correct order is -lavformat -lavcodec -lavutil. It doesnt matter 
when you use dynamic linking, but with static libs it does, because ld
does *not* scan static libraries repeatedly, only once (that is, once
per -l option).

#include
#include // < > 代表是用.PRO INCLUDEPATH引用的
#include "mediaplayer.h" // " " 代表是在现存Project中的文档

如何在C++中调用已经被编译好的C函数?这时必须采用“混合编译”,例如:
extern "C"
{
#include
#include
}
这里调用了ffmpeg的头文件avformat.h和avcodec.h,为了解决C++不能编译C的问题,
这里必须加在extern"C"里。原因:例如函数abcd()被C编译器编译后在库中的名字为_abcd,
而C++编译器则会产生_abcd_int_int之类的名字用来支持
函数重载和类型安全连接。由于编译后的名字不同,C++程序不能直接调用C函数。
C++提供了一个C连接交换指定符号extern “C” 来解决这个问题。

2008年11月30日星期日

Qt 及SDL

Qt部分:
可以把 QWidget包成一個QDockWidget的子类,进而加到QDockWidget中,例如:

SDLVideo *SDLVideo_dock = new SDLVideo; 
QDockWidget *dock_4 = new QDockWidget(tr("Media Player of Online Tool of Robotic Experiment"), this); 
dock_4->setWidget(SDLVideo_dock); // 重点:把 QWidget包成一個QDockWidget的子类 
addDockWidget(Qt::LeftDockWidgetArea, dock_4); 
viewMenu->addAction(dock_4->toggleViewAction()); 

再介绍两个有趣的函数:

setAttribute(Qt::WA_PaintOnScreen);//这个函数可以给屏幕截图 
setUpdatesEnabled(false);//可以决定是否对Widget截的图是否可以Update 

SDL部分:

putenv("SDL_VIDEODRIVER=directx"); 

注意:这个函数必须用在SDL_Init();之前才有实际效果。来设置为directx环境。(VC下为了解除编译警告,也可使用SDL_putenv()来代替putenv(),效果都一样。)

以下程序实例--让SDL结合在Qt Widget里,摘自:http://www.guiadohardware.net/comunidade/showthread.php?t=797107
我试了,可以用,但是还不是很完美的解决方案。
如何用SDL创建一个窗口: 一个台湾网友的LinuxGame的博客,中文说明http://otlinux.blogspot.com/2007_12_01_archive.html

英文版http://www.aaroncox.net/tutorials/2dtutorials/sdlwindow.html

如何让SDL嵌入到Qt的Widget里,使用:QWidget::winId()
至今为止,最好的解决方案。例1: http://listas.apesol.org/pipermail/sdl-libsdl.org/2005-September/051604.html

#define NEED_SDL_GETENV 
#include 
//.... 
char variable[256]; 
sprintf(variable, "SDL_WINDOWID=0x%lx", winId()); 
if (SDL_putenv(variable) == -1) 
{ 
// .... 
}

例2:http://stackoverflow.com/questions/118659/how-do-i-use-qt-and-sdl-together

// Set the new video mode with the new window size 
char variable[64]; 
snprintf(variable, sizeof(variable), "SDL_WINDOWID=0x%lx", winId()); 
putenv(variable); 
// ffmpeg is relatively simple. 
// A while back, I used the page below as a reference 
// and coded up a simple app that uses ffmpeg to decode frames 
// and paints them on screen in a QWidget. 

http://www.inb.uni-luebeck.de/~boehme/libavcodec_update.html

2008年11月29日星期六

SDL库在Qt .pro中设定

在.pro 里加上以下的Script:
INCLUDEPATH = "C:\SDL-devel-1.2.13-mingw32\SDL-1.2.13\include\SDL"
win32:LIBS += -L"C:\MinGW\lib" -lmingw32 \
-L"C:\SDL-devel-1.2.13-mingw32\SDL-1.2.13\lib" -lSDLmain -lSDL
注意1: INCLUDEPATH的双引号可加可不加,win32:LIBS的双引号最好加上

2:win32:LIBS加入的顺序是很重要的

3:用 \ 和 / 效果是一样的对于连接

4:不同的文档用 \ 相隔

5:当写-L时,写-lSDLmain而不是libSDLmain.a 等等,注意写的规范性。

举一个实例:让使用Qt的项目(使用MinGW gcc)可以编译SDL_image
1.在.pro中加入
INCLUDEPATH = C:\SDL_image-1.2.7\include
win32:LIBS += C:\SDL_image-1.2.7\lib\SDL_image.lib
2.将C:\SDL_image-1.2.7\lib中的.dll文件拷到C:\WINDOWS\system32里去
3.在所需的C++文件中加入头文件:#include "SDL_image.h"



2008年11月28日星期五

Qt qmake Makefile设置

从Qt提供的许多现存的源程序中找到相关的.pro项目文件,它们是学习qmake 更多技巧的最佳范例。

Makefile -->用 make 来开发和编译程式的确很方便 --> Makefile可以像这样由\".pro\"文件生成 --> qmake -o Makefile hello.pro (使用qmake作为Qt库和Qt所提供的工具的主要连编工具)用qmake 和.pro 文件一起生成 Makefile
--> 只需要写.pro 文件来链接它不同的链接库等等... ...


We will use qmake to build the executable, so we need to write a .pro file:
以下英文简介来自qmake用户手册:
Declaring Other Libraries
If you are using other libraries in your project in addition to those supplied with Qt, you need to specify them in your project file.
The paths that qmake searches for libraries and the specific libraries to link against can be added to the list of values in the LIBS variable. The paths to the libraries themselves can be given, or the familiar Unix-style notation for specifying libraries and paths can be used if preferred.
For example, the following lines show how a library can be specified:
LIBS += -L/usr/local/lib -lmath
The paths containing header files can also be specified in a similar way using the INCLUDEPATH variable.
For example, it is possible to add several paths to be searched for header files:
INCLUDEPATH = c:/msdev/include d:/stl/include


qmake 使用储存在项目(.pro)文件中的信息来决定Makefile文件中该生成什么,简单的说,所谓的设置配置的信息,就是在项目(.pro)文件中设定。 一个基本的项目文件包含关于应用程序的信息,比如,编译应用程序需要哪些文件,并且使用哪些配置设置。 这里是一个简单的示例项目文件:
SOURCES = hello.cpp
HEADERS = hello.h
CONFIG += qt warn_on release
Makefile可以设定使得 Qt Program可以被编译和链接(linken)。
例如:
win32:LIBS = $(QTDIR)/lib/qt-mt230nc.lib \ $(QTDIR)/lib/qtmain.lib
或:
win32:LIBS += C:/DXSDK/Lib/amstrmid.lib \
C:/DXSDK/Lib/d3d8.lib \
C:/DXSDK/Lib/d3d9.lib
不要忘了:路径中是用 / 相连!!.lib之间用 \ 相隔。
进阶阅读:如何用qmake快速生成makefile

2008年11月27日星期四

Qt-Phonon

刚刚发现有一个很好用的工具在Eclipse:Project View --> properties --> Restore from Local History (可以将以前误删的文件找回)
以下是一个德国高手关于Phonon在WinXP的安装的介绍,是我至今看到最好的。阅读时请注意:这个是对于Qt对于Microsoft Visual Studio的,对于Qt和MinGW则无法进行操作,Qt的官方网站上已经有说道,我就是看介绍太不仔细,居然 没看到:Warning: The MinGW version of Qt does not support building the Qt backend. 所以,在这里我用的是MinGW + Qt openSource + Eclipse是无法building Qt backend 的.
以下我摘抄的要点,对于Microsoft Visual Studio的:
Compilation of Phonon under Windows XP

注意:Patch SDKs
Wired but true, the Windows SDK does not compile. It is somehow broken. You need to do the following:
Add the following line
#include "rpcsal.h"
to linenumber 32 in files
C:\Programme\Microsoft SDKs\Windows\v6.1\Include\medparam.h
C:\Programme\Microsoft SDKs\Windows\v6.1\Include\mediaobj.h .pro for qmake:
INCLUDEPATH = C:\DXSDK\Include \ C:\Program Files\Microsoft SDKs\Windows\v6.1\Include
LIBPATH += C:\Program Files\Microsoft SDKs\Windows\v6.1\Lib
产生: phonon.bat以及Configure"%PROGRAMFILES%\Microsoft DirectX SDK (April 2007)\utilities\bin\dx_setenv.cmd"
%PROGRAMFILES%\Microsoft SDKs\Windows\v6.1\Bin\SetEnv.Cmd
The last one should only be necessary if you use the Express Version, but it is no problem if is called anyway
注意:请使用Qt Command Prompt 然后进入Qt的目录执行configure.exe : If your environment is setup correctly, executing configure.exe on your Qt installation should automatically activate Phonon.

2008年11月23日星期日

实战Qt .ui文档

首先,关于uic的一些小小的点,很有必要知道的:
The uic tool converts xxxx.ui into C++ and puts the result in ui_xxxx.h.
The generated ui_xxxx.h file contains the definition of the Ui::xxxx class, which is a C++ equivalent of the xxxx.ui file.
如果编译出错: launch failed no binaries

解决方法: 在 project-> properties 中把 c/c++ make project 的 binary parse 进行设置到 PE windows parsers
使用Qt Designer Editor生成的example.ui -->其对应的example.cpp 和 example.h 有ui.setupUi(this);
private:
Ui::ExampleToolClass ui;
的文件,其原文档在ui_example.h里可以使用它的一些设定,这个文件由BUILD生成的。
windows的qt里有个uic.exe
qt4
uic xxx.ui -o xxx.h
把UIC.exe和你要转换的xxx.ui文件拷贝到同一目录。
开始菜单,运行CMD
进入uic.exe和xxx.ui的目录,运行以下命令:
uic xxx.ui -o xxx.h 生成.h文件
uic xxx.ui -i xxx.h -o xxx.cpp 生成.cpp文件
uic -o myform.h myform.ui # generate header file
uic -o myform.cpp -impl myform.h myform.ui # generate implementation file
uic -o myformimpl.h -subdecl MyFormImpl myform.h myform.ui # generate subclass header file
uic -o myformimpl.cpp -subimpl MyFormImpl myformimpl.h myform.ui # generate subclass implementation file
如何修改.h文件:但在QT4在Windows下面 -->OpenSource版只有界面设计功能,其它的就沒了--> 用纯代码进行界面设计师必要的,也是非常重要的,QT Designer只是为了加快界面开发。在自己定义的类里加一个Qt Designer里生成的类的成员,並SetupUi()安裝它,所有在Designer里设计不到的部分,在自定义类里进行处理。
看QT Assistant -->QT Designer的用法的那部分帮助。
有两种方法创建GUI 使用 Qt:
使用直接编程法,我个人推荐这种方法。比较容易生成链接,比较容易进行signal and slot的处理。只需建立xxx.h和xxx.cpp文件,无需建立Qt class之类的文件. 
使用Qt Designer: 它会生成ui_xxx程序(会自动生成,或可以用UCI程序生成),可以把它分解成两部分xxx.h和xxx.cpp但是不是那么容易,然后进行编程。

还有一种比较直接的方法,我称其为:"结合使用法",详细见:以下推荐的书的原版35页。

C++ GUI Programming with Qt 4中文版

2008年11月21日星期五

使用Qt Eclipse integration加文件到项目里,资源管理,项目管理

加文件到项目里Adding Files to the Project
要增加文件到在Eclipse的一个Qt项目,有二步是必要。首先,文件必须增加到工作区,并且第二,文件必须增加到.pro文件。如果你想要增加一个新的源文件到你的项目,File|New|Source File wizard 和enter 文件名。 Source 文件夹线编辑指定文件将增加的工作区项目。在点击结束以后,项目范围选择器对话框将出现。这对话框显示项目的.pro文件的所有被定义的范围,并且文件可以增加的variable 。在源文件情况下, “源文件”variable 和“标头文件”variable 被显示。 选择应该插入源文件的范围然后点击OK。现在,新的文件是a)增加到工作区和b)被添附到“源文件”variable在.pro文件里。 因为改变了.pro文件,它在编辑被打开并且被标记以被修改。 因此,记住在开始build之前保存.pro文件。
Managing Resources资源管理
要增加新的资源resources,你必须首先创造一个新的.qrc文件。打开File|New|Other... dialog,选择从Qt文件夹里Qt资源文件项目,并且点击Next。 新创建的.qrc文件将被显示在Eclipse上。.qrc文件只包含称/new/prefix1的前缀。你能增加资源在那前缀之下通过点击Add。当稍后关于资源从Qt代码来时,你必须加在前面前缀文件名加在冒号(即, :/new/prefix1/print.bmp)。 对于增加新的前缀,点击在增加按钮的箭头,并且选择Add前缀。 前缀的名字和资源的别名可以更改 with the line edits 在资源视图之下。

项目管理
使用.pro File Editor可以很轻松的利用它所提供的GUI对Project进行管理和改变,在Qt中这是一个很实用的技巧。
详细的例子请:如何进行Project管理


Qt Designer Editor也是很有用的程序,我们可以用它来设计GUI,例如,我们可以使用它改变字的颜色:在 Qt Designer Editor里: Display Widgets --> Label --> Property --> Point Size, text (改名称和大小), 在版上点Label按鼠标右键 --> change rich text --> 可改字的颜色。


2008年11月19日星期三

使用Eclipes开始第一个Qt例程

首先注意:可以新建一个WORKSPACE因为,Eclipse对于一个Project都需要一个新的WORKSPACE这样就可以把这个Project的所有的东西放在里面,当新建一个WORKSPACE可能要新设置Qt的位置。
先生成一个Qt应用框架
调用New Project dialog in Eclipse --> 点Qt folder --> Qt Gui Project --> 点击 Next -->输入 "AddressBook" 到 Project Name field (对于 "AddressBook" 例子里) --> 点Finish.
当Eclipse 发现 Qt 的位置, the project 这时可以被编译. -->进入 Project menu --> Build Project.
现在可以启用"AddressBook" application,在"AddressBook" project in the "C/C++ Projects" view里, 选 Run|Open Run Dialog... dialog 然后双击C/C++ Local Application item 用于产生一个新的RUN配置。最后 click the Run 按钮。
然后加入构件(Adding the Widgets)
展开 Qt Designer, 双击 addressbook.ui 文件。
先让Qt C++ Widget Box 可视:Window --> Show View --> Other --> Qt --> Qt C++ Widget Box 可让Qt C++ Widget Box出现在View里
开始先见到 QListWidget。 展开 Qt C++ Widget Box, 然后点击 List Widget subitem 并将它拖动到form的左上角. Qt C++ Property Editor (Window|Show View|Qt C++ Property Editor) 将会展示QListWidget的属性.使用property editor, 将objectName property 设为 "addressList".
现在可以试着插入Add and Delete buttons. 在 Qt C++ Widget Box and 拖动两个 Push Buttons 到form的右上角. 将 buttons 改名为 "addButton" and "deleteButton", 将它们的text property(文字属性)设为 "Add" and "Delete"。
哈哈很简单吧。现在已经完成了一个小的widget。

接下来可以看详细的教程.试着完成后面几步。

2008年11月18日星期二

如何让SDL窗口嵌入Qt窗口

先简单介绍一下SDL:

SDL(Simple DirectMedia Layer)是一套开放原始码的跨平台多媒体开发函式库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函式,让开发者只要用相同或是相似的程式码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软体。目前SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。
虽然SDL时常被比较为‘跨平台的DirectX’,然而事实上SDL是定位成以精简的方式来完成基础的功能,它大幅度简化了控制图像、声音、输出入等工作所需撰写的程式码。但更高阶的绘图功能或是音效功能则需搭配OpenGL和OpenAL等API来达成。另外它本身也没有方便建立GUI的函式。

但是如何让SDL窗口嵌入Qt的Widget里(render videos, audioes and images under GUI(made of Qt) using SDL. The sdl screen must be successfully integrated into qt screen.) ?
(Implement SDL in a QT widget-- how to integrate SDL into Qt? )
有两种方法用于解决这个问题,一个是间接法如 solution 1 ,一个是直接法如 solution 2. 以下是从网上收集的说明。

Solution 1: Using a seperate thread for rendering:

The easiest and sanest solution would be to decouple both parts. So that SDL and Qt run in separate processes and have them use some kind of messaging to communicate. SDL can be rendered into borderless window and the editor sends commands via messages.

using a seperate thread for rendering.
This thread could run on its own in the background and you simply could use your Qt-buttons to stop/pause/resume the thread.

If you want your SDL-window to react when a real key is pressed, it would be a viable solution to simulate key events from Qt.

If you want to just signal the SDL-code in some way I'd suggest using custom events (SDL_UserEvent).
For example, do something like this:

  1. Start App and open Qt-Window
  2. Initialize SDL and open output window
  3. Create thread that updates SDL-Window waits for some signal to stop/pause/resume or for xx seconds
  4. Use the SLOTs called by your Qt-Buttons to signal the thread to stop/pause/resume (using Key- or UserEvents? or using flags being set by Qt's main-thread) [/list=1]
Solusion 2: Direct way to integrate SDL into Qt:

put the SDL overlay window on the top of Qt window by using the following 3 steps.
1) create SDL window according to the size of Qt window.
2) create SDL window without frame (SDL_NOFRAME).
3) move SDL window based on the top-right coop. of SDL window (xMoveWindow())

Following functions from SDL are mainly used,
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
SDL_GetWMInfo(&info);
p_container->embed(info.info.x11.wmwindow, false).

链接集合:OpenGL,Ffmpeg等等

习Qt除了装软件还要准备一两本书。我推荐C++ GUI Programming with Qt4, 在网上甚至可以收到它的PDF版。http://www.qiliang.net/qt/index.html Qt参考文档,这个网站也是很值得推荐的,它有一个很热心的中国工程师建立的,内容非常实用,中文资料的好处在于我们可以非常快速的阅读和检索我们所需要的资料。
关于 Qt设计器 部分很值得一读。
Qt设计器是用来设计和实现用户界面并能够在多平台下使用的一种工具。Qt设计器可以使用户界面设计实验变得简单。在任何时候你可以要求所生成的代码去重建Qt设计器产生的用户界面文件,并可以根据你的喜好来改变你的设计。
当然的trolltech 上提供的资料是最丰富的:http://trolltech.com/ 很适合进阶阅读。

OpenGL(全写Open Graphics Library)是个定义了一个跨程式语言、跨平台的编程接口的规格, 为三维绘图提供的标准应用编程接口。OpenGL处理的仅仅是三维绘图方面,而很少或是根本不提供图形用户界面编程方面的支持。OpenGL 的 GUI 必须由其它工具包创建,比如Qt。Qt的OpenGL模块使在Qt应用程序中使用OpenGL变的更加容易。它提供了一个OpenGL的部件类,这个部件类除了打开一个OpenGL显示缓冲,利用这个缓冲使用OpenGL应用编程接口来提供内容外,能像其它Qt部件那样的使用。

Starting out with OpenGL 2.1: 这是一个简单的 study guide.

QGLWidget

在Qt中OpenGL提供支持的类为:

  • QGLWidget:一个容易使用的Qt部件,它提供了OpenGL场景。
  • QGLContext:封装了OpenGL提供的上下文。
  • QGLFormat:对于一个给定的上下文,指定特定的显示模式。
  • QGLColormap:在GL-index中处理编入索引的colormaps。
FFmpeg是一个免费开放原码 的软体,可以执行音讯和视讯多种格式的的录影、转档、串流功能,包含了libavcodec ─这是一个用于多个专案中音讯和视讯的解码器函式库,以及 libavformat ——一个音讯与视讯格式转换函式库。FFmpeg is a complete solution to record, convert and stream audio and video. It includes libavcodec, the leading audio/video codec library. FFmpeg is developed under Linux, but it can compiled under most operating systems, including Windows.
视频技术论坛 » FFMPEG工程组
FFMPEG参数说明
: http://leezen.blogbus.com/logs/19276689.html
ffmpeg使用说明 http://blog.chinaunix.net/u/16166/showart_239248.html
An ffmpeg and SDL Tutorial

ffdshow is a media decoder and encoder mainly used for the fast and high-quality decoding of video in the MPEG-4 ASP (e.g. encoded with DivX, Xvid or FFmpeg MPEG-4) and AVC (H.264) formats, but supporting numerous other video and audio formats as well. It is free software released under the GPL license, runs on Windows and is implemented as a DirectShow and VFW decoding filter.

Xvid(旧称为XviD)是一个开放原始码的MPEG-4视频编解码器,它是基于OpenDivX而编写的。XviD是最新的MPEG-4 codec,而且是第一个真正开放源代码的,一旦完成就会通过GPL协议发布.
http://www.xvid.org/
Xvid in Baidu