答:重新实现这个窗体的closeEvent()函数,加入判断操作 Quote:
void MainWindow::closeEvent(QCloseEvent *event) {
if (maybeSave()) {
writeSettings(); event->accept(); } else {
event->ignore(); } }
2、如何用打开和保存文件对话 答:使用QFileDialog Quote:
QString fileName = QFileDialog::getOpenFileName(this); if (!fileName.isEmpty()) {
loadFile(fileName); } Quote:
QString fileName = QFileDialog::getSaveFileName(this); if (fileName.isEmpty()) {
return false; }
3、如果创建Actions(可在菜单和工具栏里使用这些Action) 答:
Quote:
newAct = new QAction(QIcon(\":/images/new.png\"), tr(\"&New\"), this); newAct->setShortcut(tr(\"Ctrl+N\"));
newAct->setStatusTip(tr(\"Create a new file\"));
connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));
openAct = new QAction(QIcon(\":/images/open.png\"), tr(\"&Open...\"), this); openAct->setShortcut(tr(\"Ctrl+O\"));
openAct->setStatusTip(tr(\"Open an existing file\"));
connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
saveAct = new QAction(QIcon(\":/images/save.png\"), tr(\"&Save\"), this); saveAct->setShortcut(tr(\"Ctrl+S\"));
saveAct->setStatusTip(tr(\"Save the document to disk\")); connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));
saveAsAct = new QAction(tr(\"Save &As...\"), this);
saveAsAct->setStatusTip(tr(\"Save the document under a new name\")); connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs()));
exitAct = new QAction(tr(\"E&xit\"), this); exitAct->setShortcut(tr(\"Ctrl+Q\"));
exitAct->setStatusTip(tr(\"Exit the application\"));
connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
cutAct = new QAction(QIcon(\":/images/cut.png\"), tr(\"Cu&t\"), this); cutAct->setShortcut(tr(\"Ctrl+X\"));
cutAct->setStatusTip(tr(\"Cut the current selection's contents to the \" \"clipboard\"));
connect(cutAct, SIGNAL(triggered()), textEdit, SLOT(cut()));
copyAct = new QAction(QIcon(\":/images/copy.png\"), tr(\"&Copy\"), this); copyAct->setShortcut(tr(\"Ctrl+C\"));
copyAct->setStatusTip(tr(\"Copy the current selection's contents to the \" \"clipboard\"));
connect(copyAct, SIGNAL(triggered()), textEdit, SLOT(copy()));
pasteAct = new QAction(QIcon(\":/images/paste.png\"), tr(\"&Paste\"), this); pasteAct->setShortcut(tr(\"Ctrl+V\"));
pasteAct->setStatusTip(tr(\"Paste the clipboard's contents into the current \" \"selection\"));
connect(pasteAct, SIGNAL(triggered()), textEdit, SLOT(paste()));
aboutAct = new QAction(tr(\"&About\"), this);
aboutAct->setStatusTip(tr(\"Show the application's About box\")); connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
aboutQtAct = new QAction(tr(\"About &Qt\"), this);
aboutQtAct->setStatusTip(tr(\"Show the Qt library's About box\")); connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
4、如果创建主菜单
答:采用上面的QAction的帮助,创建主菜单 Quote:
fileMenu = menuBar()->addMenu(tr(\"&File\")); fileMenu->addAction(newAct); fileMenu->addAction(openAct); fileMenu->addAction(saveAct); fileMenu->addAction(saveAsAct); fileMenu->addSeparator(); fileMenu->addAction(exitAct);
editMenu = menuBar()->addMenu(tr(\"&Edit\")); editMenu->addAction(cutAct); editMenu->addAction(copyAct); editMenu->addAction(pasteAct);
menuBar()->addSeparator();
helpMenu = menuBar()->addMenu(tr(\"&Help\")); helpMenu->addAction(aboutAct); helpMenu->addAction(aboutQtAct);
5、如果创建工具栏
答:采用上面的QAction的帮助,创建工具栏 Quote:
fileToolBar = addToolBar(tr(\"File\")); fileToolBar->addAction(newAct); fileToolBar->addAction(openAct); fileToolBar->addAction(saveAct);
editToolBar = addToolBar(tr(\"Edit\"));
editToolBar->addAction(cutAct); editToolBar->addAction(copyAct); editToolBar->addAction(pasteAct);
6、如何使用配置文件保存配置 答:使用QSettings类 Quote:
QSettings settings(\"Trolltech\
QPoint pos = settings.value(\"pos\ QSize size = settings.value(\"size\ Quote:
QSettings settings(\"Trolltech\ settings.setValue(\"pos\ settings.setValue(\"size\
7、如何使用警告、信息等对话框 答:使用QMessageBox类的静态方法 Quote:
int ret = QMessageBox::warning(this, tr(\"Application\"), tr(\"The document has been modified.\\n\" \"Do you want to save your changes?\"), QMessageBox::Yes | QMessageBox::Default, QMessageBox::No,
QMessageBox::Cancel | QMessageBox::Escape); if (ret == QMessageBox::Yes) return save();
else if (ret == QMessageBox::Cancel) return false;
8、如何使通用对话框中文化 答:对话框的中文化
比如说,QColorDialog的与文字相关的部分,主要在qcolordialog.cpp文件中,我们可以从qcolordialog.cpp用 lupdate生成一个ts文件,然后用自定义这个ts文件的翻译,再用lrelease生成一个.qm文件,当然了,主程序就要改变要支持多国语言了,使用这
个.qm文件就可以了。
另外,还有一个更快的方法,在源代码解开后有一个目录translations,下面有一些.ts, .qm文件,我们拷贝一个: Quote:
cp src/translations/qt_untranslated.ts ./qt_zh_CN.ts
然后,我们就用Linguist打开这个qt_zh_CN.ts,进行翻译了,翻译完成后,保存后,再用lrelease命令生成qt_zh_CN.qm,这样,我们把它加入到我们的qt project中,那些系统的对话框,菜单等等其它的默认是英文的东西就能显示成中文了。
9、在Windows下Qt里为什么没有终端输出? 答:把下面的配置项加入到.pro文件中 Quote:
win32:CONFIG += console
10、Qt 4 for X11 OpenSource版如何静态链接? 答:编译安装的时候加上-static选项 Quote:
./configure -static //一定要加static选项 gmake gmake install
然后,在Makefile文件中加 static 选项或者在.pro文件中加上QMAKE_LFLAGS += -static,就可以连接静态库了。
11、想在源代码中直接使用中文,而不使用tr()函数进行转换,怎么办? 答:在main函数中加入下面三条语句,但并不提倡 Quote:
QTextCodec::setCodecForLocale(QTextCodec::codecForName(\"UTF-8\")); QTextCodec::setCodecForCStrings(QTextCodec::codecForName(\"UTF-8\")); QTextCodec::setCodecForTr(QTextCodec::codecForName(\"UTF-8\")); 或者 Quote:
QTextCodec::setCodecForLocale(QTextCodec::codecForName(\"GBK\"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName(\"GBK\")); QTextCodec::setCodecForTr(QTextCodec::codecForName(\"GBK\"));
使用GBK还是使用UTF-8,依源文件中汉字使用的内码而定 这样,就可在源文件中直接使用中文,比如: Quote:
QMessageBox::information(NULL, \"信息\\"关于本软件的演示信息\QMessageBox::Ok, QMessageBox::NoButtons);
12、为什么将开发的使用数据库的程序发布到其它机器就连接不上数据库? 答:这是由于程序找不到数据库插件而致,可照如下解决方法: 在main函数中加入下面语句: Quote:
QApplication::addLibraryPath(strPluginsPath\");
strPluginsPath是插件所在目录,比如此目录为/myapplication/plugins 则将需要的sql驱动,比如qsqlmysql.dll, qsqlodbc.dll或对应的.so文件放到 /myapplication/plugins/sqldrivers/ 目录下面就行了
这是一种解决方法,还有一种通用的解决方法,即在可执行文件目录下写qt.conf文件,把系统相关的一些目录配置写到qt.conf文件里,详细情况情参考Qt Document Reference里的qt.conf部分
13、如何创建QT使用的DLL(.so)以及如何使用此DLL(.so) 答:创建DLL时其工程使用lib模板 Quote: TEMPLATE=lib
而源文件则和使用普通的源文件一样,注意把头文件和源文件分开,因为在其它程序使用此DLL时需要此头文件
在使用此DLL时,则在此工程源文件中引入DLL头文件,并在.pro文件中加入下面配置项: Quote:
LIBS += -Lyourdlllibpath -lyourdlllibname
Windows下和Linux下同样(Windows下生成的DLL文件名为yourdlllibname.dll而在Linux下生成的为libyourdlllibname.so
14、如何启动一个外部程序
答:可使用QProcess和QThread这两个类结合使用的方法来处理,以防止在主线程中调用而导致阻塞的情况
先从QThread继承一个类,重新实现run()函数: Quote:
class MyThread : public QThread { public: void run(); };
void MyThread::run() {
QProcess::execute(\"notepad.exe\"); }
这样,在使用的时候则可定义一个MyThread类型的成员变量,使用时调用其start()方法: Quote:
class ............... {...........
MyThread thread; ............ };
..................... thread.start();
15、如何打印报表
答:Qt目前对报表打印支持的库还很少,不过有种变通的方法,就是使用XML+XSLT+XSL-FO来进行报表设计,XML输出数据,用XSLT将XML数据转换为XSL-FO格式的报表,由于现在的浏览器不直接支持XSL-FO格式的显示,所以暂时可用工具(Apache FOP, Java做的)将XSL-FO转换为PDF文档来进行打印,转换和打印由FOP来做,生成XSL-FO格式的报表可以由Qt来生成,也可以由其它内容转换过来,比如有工具(html2fo)将HTML转换为XSL-FO。
16、如何在系统托盘区显示图标
答:在4.2及其以上版本中使用QSystemTrayIcon类来实现
转自:QT中文论坛 基础篇 -- Qt4.2之后的托盘类实现托盘程序
用hello world简单的代码更容易看懂托盘的具体实现,未完待续,一些细节问题,比如为什么提示消息没有显示在托盘上,如何在tip消息上增加图标等。
复制内容到剪贴板
代码: #include class myclass: public QWidget { public: myclass(); private: QPushButton *b1; QSystemTrayIcon *trayIcon; }; myclass::myclass() { QTextCodec::setCodecForTr(QTextCodec::codecForName(\"GB2312\")); setMinimumSize(200,100); setMaximumSize(200,100); b1=new QPushButton(\"hello world\ b1->setGeometry(20,20,160,40); QIcon icon = QIcon(\"./images/bad.svg\"); setWindowIcon(icon); trayIcon = new QSystemTrayIcon(this); trayIcon->setIcon(icon); trayIcon->setToolTip(\"a trayicon example\"); QString titlec=tr(\"看吧\"); QString textc=QString::fromLocal8Bit(\"就这德行啊\"); trayIcon->show(); trayIcon->showMessage(titlec,textc,QSystemTrayIcon::Information,5000); setWindowTitle(tr(\"Systray\")); } int main(int argc,char **argv) { QApplication testc(argc,argv); myclass newc; newc.show(); return testc.exec(); } 进一步研究,加入点击托盘的响应,使提示信息显示在托盘上,未完待续托盘的右键菜单。 经验一:编译信号和槽 需要有.h .cpp这样的格式,否则不会生成相应的信号和槽; 经验二:信号和槽之间可以递参数,但是不允许函数直接给槽提供参数。 hello.h 复制内容到剪贴板 代码: #include class myclass: public QWidget { Q_OBJECT public: myclass(); private: QPushButton *b1; QSystemTrayIcon *trayIcon; char *msg; void showMessage(char *msg); private slots: void showM(); void iconActivated(QSystemTrayIcon::ActivationReason reason); }; hello.cpp 复制内容到剪贴板 代码: #include QTextCodec::setCodecForTr(QTextCodec::codecForName(\"GB2312\")); setMinimumSize(200,100); setMaximumSize(200,100); b1=new QPushButton(\"hello world\b1->setGeometry(20,20,160,40); QIcon icon = QIcon(\"./images/bad.svg\"); setWindowIcon(icon); trayIcon = new QSystemTrayIcon(this); trayIcon->setIcon(icon); trayIcon->setToolTip(\"a trayicon example\"); trayIcon->show(); setWindowTitle(tr(\"Systray\")); connect(trayIcon,SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this,SLOT(iconActivated(QSystemTrayIcon::ActivationReason))); connect(b1,SIGNAL(clicked()),this,SLOT(showM())); } void myclass::showM() { QString titlec=tr(\"slot需要signal相同的参数进行传递\"); QString textc=QString::fromLocal8Bit(\"测试内容单击、双击、中键、按钮\"); trayIcon->showMessage(titlec,textc,QSystemTrayIcon::Information,5000); } void myclass::showMessage(char *msg) { QString titlec=tr(msg); QString textc=QString::fromLocal8Bit(\"测试内容单击、双击、中键、按钮\"); trayIcon->showMessage(titlec,textc,QSystemTrayIcon::Information,5000); } void myclass::iconActivated(QSystemTrayIcon::ActivationReason reason) { switch (reason) { case QSystemTrayIcon::Trigger: showMessage(\"单击\"); break; case QSystemTrayIcon::DoubleClick: showMessage(\"双击啦\"); break; case QSystemTrayIcon::MiddleClick: showMessage(\"你用的是三轮鼠标还是滚轮鼠标啊\"); break; default: ; } } int main(int argc,char **argv) { QApplication testc(argc,argv); myclass newc; newc.show(); return testc.exec(); } 那么最后我们把所有元素都结合在一起来实现这么一个托盘程序,比较上个例子我们增加了右键菜单并使它管理窗口的大小。 hello.h 复制内容到剪贴板 代码: #include class myclass: public QWidget { Q_OBJECT public: myclass(); private: QPushButton *b1; QSystemTrayIcon *trayIcon; char *msg; void showMessage(char *msg); void createActions(); void createTrayIcon(); QAction *minimizeAction; QAction *maximizeAction; QAction *restoreAction; QAction *quitAction; QMenu *trayIconMenu; private slots: void showM(); void iconActivated(QSystemTrayIcon::ActivationReason reason); }; hello.cpp 复制内容到剪贴板 代码: #include myclass::myclass() { QTextCodec::setCodecForTr(QTextCodec::codecForName(\"GB2312\")); setMinimumSize(200,100); b1=new QPushButton(\"hello world\ b1->setGeometry(20,20,160,40); QIcon icon = QIcon(\"./images/bad.svg\"); setWindowIcon(icon); trayIcon = new QSystemTrayIcon(this); trayIcon->setIcon(icon); trayIcon->setToolTip(\"a trayicon example\"); createActions(); createTrayIcon(); trayIcon->show(); setWindowTitle(tr(\"Systray\")); connect(trayIcon,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this,SLOT(iconActivated(QSystemTrayIcon::ActivationReason))); connect(b1,SIGNAL(clicked()),this,SLOT(showM())); } void myclass::showM() { QString titlec=tr(\"slot需要signal相同的参数进行传递\"); QString textc=QString::fromLocal8Bit(\"测试内容单击、双击、中键、按钮\"); trayIcon->showMessage(titlec,textc,QSystemTrayIcon::Information,5000); } void myclass::showMessage(char *msg) { QString titlec=tr(msg); QString textc=QString::fromLocal8Bit(\"测试内容单击、双击、中键、按钮\"); trayIcon->showMessage(titlec,textc,QSystemTrayIcon::Information,5000); } void myclass::iconActivated(QSystemTrayIcon::ActivationReason reason) { switch (reason) { case QSystemTrayIcon::Trigger: showMessage(\"单击\"); break; case QSystemTrayIcon::DoubleClick: showMessage(\"双击啦\"); break; case QSystemTrayIcon::MiddleClick: showMessage(\"你用的是三轮鼠标还是滚轮鼠标啊\"); break; default: ; } } void myclass::createActions() { minimizeAction = new QAction(tr(\"最小化 (&I)\"), this); connect(minimizeAction, SIGNAL(triggered()), this, SLOT(hide())); maximizeAction = new QAction(tr(\"最大化 (&X)\"), this); connect(maximizeAction, SIGNAL(triggered()), this, SLOT(showMaximized())); restoreAction = new QAction(tr(\"还原 (&R)\"), this); connect(restoreAction, SIGNAL(triggered()), this, SLOT(showNormal())); quitAction = new QAction(tr(\"退出 (&Q)\"), this); connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit())); } void myclass::createTrayIcon() { trayIconMenu = new QMenu(this); trayIconMenu->addAction(minimizeAction); trayIconMenu->addAction(maximizeAction); trayIconMenu->addAction(restoreAction); trayIconMenu->addSeparator(); trayIconMenu->addAction(quitAction); trayIcon->setContextMenu(trayIconMenu); } int main(int argc,char **argv) { QApplication testc(argc,argv); myclass newc; newc.show(); return testc.exec(); } qvfb 1 关于QVFB Qvfb 是为qtopia做的一个虚拟frambuffer的应用程序,它的最终目 的就是把qtopia应用程序运行的的结果显示在qvfb上(实际中是要通过linux的frambuffer驱动显示在lcd屏上的),并提供键盘、鼠标的外设仿真。从而方便研发阶段,用户在pc端就可以完成qtopia的调试工作,极大的提高了工作效率。 2 QVFB概述 Qvfb本身其实也是一个应用程序,qtopia也是一个应用程序,二者 通过既定协议完成通信,如下图示。 更直观一点,如下图示。 Qpe和qvfb之间的通讯是基于既定的协议进行的,qpe和qvfb独立运行,它们处于不同的进程,它们之间以“共享内存”的方式完成通讯。 3 qpe端接口 Qtopia 中server 端启动时,会调用QVFbScreen::connect()函数来连 接到屏幕,这里qpe会创建一块共享内存,模拟framebuffer,用于图象的输出,针对键盘鼠标分别创建两个文件,其名字由两个宏来决定,为QT_VFB_MOUSE_PIPE和QT_VFB_KEYBOARD_PIPE。 关于图形绘制,qpe是通过QSCreen的派生类QVFbScreen来实现的,具体如下。 QSCreen定义了接口exposeRegion和blit,这两个函数会完成具体的绘制操作,不管是虚拟framebuffer还是真正的framebuffer,qtopia会将用于绘制的显示缓存映射到data变量,这样绘制操作就变成向data写数据了。 关于鼠标 Qtopia通过QVFbMouseHandler来完成,其构造函数中会打开约定的文件,键盘数据的获取就变成了文件的读取。 关于键盘 Qtopia通过QVFbKeyboardHandler来实现,其构造函数中会打开约定 的文件,键盘数据的获取就变成了文件的读取。 4 qvfb端介绍 Qvfb 实际上是一个用qt实现的完整的应用程序,其架构层次图如下 图示。 分别作如下阐述 4.1层次划分 QVFb是主控件,可以理解为qvfb应用的主窗口 Skin用来管理皮肤,QVFbView用于管理qpe绘制的窗口。 QVFb、Skin、QVFbView三者属于应用框架层,管理应用程序的架构。 QVFbViewProtocol是协议层,它是一个虚类,具体实现了两个类QMMapViewProtocol和QShMemViewProtocol,分别代表内存映射和共享内存,是两种实现linux上进程间通讯的方式,默认使用共享内存方式。协议层具体实现待绘制数据的获取以及屏幕的更新。 架构和实现分离,层次清晰。 4.2图形绘制 讲述屏幕图象绘制的流程 QShMemViewProtocol的构造函数 创建共享内存,影射到hdr指针,分配显示区域的内存空间,影射到dataCache,建 立timer mRefreshTimer = new QTimer( this ); connect( mRefreshTimer, SIGNAL(timeout()), this, SLOT(flushChanges()) ); 函数flushChanges会定期执行,它就是qvfb窗口绘制的源头。 QVFbView的构造函数 mView = new QShMemViewProtocol(id, QSize(_w, _h), d, this); connect(mView, SIGNAL(displayDataChanged(const QRect &)), SLOT(refreshDisplay(const QRect &))); 将QShMemViewProtocol中的信号displayDataChanged绑定到QVFbView的槽函数refreshDisplay。 看看flushChanges函数的实现 void QShMemViewProtocol::flushChanges() { // based of dirty rect, copy changes from hdr to hdrcopy QRect r; { DisplayLock(); if (hdr->dirty) { r = hdr->update; hdr->dirty = false; hdr->update = QRect(); /* copy the memory area */ /* for now, be inefficient. */ memcpy(dataCache, ((char *)hdr) + hdr->dataoffset, displaySize); } } emit displayDataChanged(r); } 可以看到该函数作两件事情,一是从共享内存中copy数据到dataChche,二是发出displayDataChanged信号。 看看refreshDisplay函数的实现 void QVFbView::refreshDisplay(const QRect &r) { if ( animation ) { if ( r.isEmpty() ) { animation->appendBlankFrame(); } else { int l; QImage img = getBuffer( r, l ); animation->appendFrame(img,QPoint(r.x(),r.y())); } } if ( !r.isNull() ) repaint(); } 该函数最终会触发paintEvent来完成绘制,绘制过程会通过协议层(也就是dataCache)来获取数据,最终绘制到窗口上。 4.3 键盘鼠标 关于skin Skin直接受鼠标事件,由mousePressEvent、mouseReleaseEvent负责。最终会调用协议层QShMemViewProtocol中的QVFbMousePipe去发送鼠标事件,最终会写到协议规定的文件中去,qpe端通过读取该文件获取鼠标事件。 关于QVFbView 会接受鼠标、键盘事件,由mousePressEvent、mouseReleaseEvent、keyPressEvent、 keyReleaseEvent。最终也是调用协议层QShMemViewProtocol中的QVFbMousePipe和 QVFbKeyPipeProtocol去发送鼠标、键盘事件,也就是写到既定的文件中,最终由qpe通过读取文件来获取鼠标、键盘事件。 5 关于qvfb的扩展 扩展qvfb,使其能够支持audio和video,从而方便在pc端调试多媒体方面的模块,也可以脱离开发板,也提高开发效率。从qpe和qvfb配合工作的现有架构上看,上述工作的可行性是有的。 5.1 auido模块的添加 在现有的基础上添加audio模块,放到协议层中即可。 并添加QVFbAudioPipe *audio到QShMemViewProtocol中去,定义一个audio文件存放音频数据,qpe端写入,qvfb端读出并写到声卡中去。 至于如何实现音频播放,最简单的做法是在现有基础上添加。 void QShMemViewProtocol::flushChanges()函数是图象的绘制起点,可以在这里添加audio数据的获取,然后在void QVFbView::refreshDisplay(const QRect &r)里写入声卡,完成音频播放。 当然qpe端音频相关的输出,要写入既定文件了,这里要实现一层替代als音频访问的接口。 5.2 video模块的添加 现有qvfb已经实现了绘制工作,要支持多媒体模块的pc端调试,qvfb这边不需要象audio那样添加新模块。Qpe端要作些修改,添加一层v4l2的接口层,把其影射到既定的文件中去,qvfb端照常显示。 5.3 关于音视频同步 音视频同步是多媒体应用层去负责的事情,qvfb端只要保证音视频数据的及时输出就可以了。 发表于: 2008-07-11,修改于: 2008-07-11 21:25,已浏览358次,有评论0条 推荐 投诉 在QT中调用mplayer 发布日期:2008/6/6 13:54:31 人气指数:37 选择内容区背景色: (字体大小:大 中(默认) 小 | 逐渐变大 逐渐变小) 【语言/語言/Language/언어/言語:简体中文 | 繁體中文 | English | 한국어 | 日本語】 正常浏览 | 发布资讯 | 评论 | 置顶 | 打印 如果是想在QT之外打开一个mplayer窗口就很容易: const QString mplayerPath(\\\"D:/tools/mplayer/mplayer.exe\\\"); QStringList args; args<<\\\"2.avi\\\"; QProcess* myProcess=new QProcess; myProcess->start(mplayerPath,args); 如果是想在QT的窗口里用mplayer,就像smplayer那像,这可不是件容易的事。 在 网 上 只 找 到 一 上 法 文 的 例 子 : http://doc.qtfr.org/post/2007/03/21/Un-conteneur-pour-MPlayer-utilisation-de-QProcess 用QProcess实现的。可用google英文翻译后阅读。 代码在:http://doc.qtfr.org/public/2007/qt_mplayer.tar.gz 我在windows下实验成功。 也可以研究一下smplayer的源码。大体思想是(别人总结的,跟上面的例子一样): 发现mplayer的参数-wid可以把输出流重定向的指定的窗体,通过winId()得到窗体的id即可,但是我不知道视频流或者说外部显示的数据是怎么在Qwidget上呈现的。 这是那个法国人的例子程序,我加了些comment,注意要把2.avi放到release文件夹下,执行可执行程序,而不是编译后点运行: #include #include #ifdef Q_OS_WIN32 const QString mplayerPath(\\\"D:/tools/mplayer/mplayer.exe\\\"); #else const QString mplayerPath(\\\"/usr/bin/mplayer\\\"); #endif const QString movieFile(\\\"2.avi\\\"); class PlayerWidget: public QWidget ...{ Q_OBJECT private: QPushButton *controller; QWidget *renderTarget; QProcess *mplayerProcess; //main thing bool isPlaying; QSlider *timeLine; QTimer *poller; QTextEdit *log; public: PlayerWidget(QWidget *parent =0) :QWidget(parent), isPlaying(false) ...{ controller = new QPushButton(\\\"Play\\\"); renderTarget = new QWidget(this); [Page] renderTarget->setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred)); renderTarget->setAttribute(Qt::WA_OpaquePaintEvent ); renderTarget->setMinimumSize(500, 500); timeLine = new QSlider(Qt::Horizontal); log = new QTextEdit; log->setReadOnly(true); QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(controller); layout->addWidget(renderTarget); layout->addWidget(timeLine); layout->addWidget(log); setLayout(layout); mplayerProcess = new QProcess(this); poller = new QTimer(this); connect(controller, SIGNAL(clicked()), this, SLOT(switchPlayState())); //switchPlayState在后面 connect(mplayerProcess, SIGNAL(readyReadStandardOutput()), this, SLOT(catchOutput())); //catchOutput在后面 connect(mplayerProcess, SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(mplayerEnded(int, QProcess::ExitStatus))); //mplayerEnded在后面 connect(poller, SIGNAL(timeout()), this, SLOT(pollCurrentTime())); //pollCurrentTime在后面 来源:收集整理于互联网 本文主要是解决Qt中QGraphicsAbstractShapeItem,QPixmap,QPainter等组件的透明化显示问题。 在Qt中定义了一个常量,用于设置透明的颜色,即Qt::transparent,表示RGBA值为(0,0,0,0)的透明色。 在QGraphicsAbstractShapeItem的集成类中,可以把某些部分画成Qt::transparent来设置透明。 在QPainter中,可以通过setBackgroundMode()选择两种不同的背景模式,一种是Qt::TransparentMode,另外一 种是Qt::OpaqueMode。在Qt::TransparentMode模式下,背景本身就是透明的,此时QPainter的 setBackground()函数不起作用;在Qt::OpaqueMode模式下,通过QPainter的setBackground()函数来设置 QPainter类对象的背景色,在此模式下,也可以设置背景色为Qt::transparent。 有时,我们要把QPainter画到QPixmap中以防止闪烁。如果需要设置QPixmap的透明,可以先用QPixmap的fill()函数先把场景设置成透明的( fill(Qt::transparent) )。 因篇幅问题不能全部显示,请点此查看更多更全内容