Qt Programming TipsHere are Qt programming tips. Qt seems to be a GUI tool for many platformdevelopment. Linux part can be had for free. I'm using Qt for OpenGL application development. UPDATE:The availability of a book C++ GUI Programming with Qt3 (J.Blanchette andM. Summerfield, Prentice Hall PTR and Trolltech Press, 2004) changed thesituation completely. This book comes with a CD which contains theQt3.2 Windows and MacOSX version. For Windows version, it is really annoying to see non-commercial in all window titles, i.e. applications and dialogs, but it is Qt3.2. MacOSX version does not have this problem.I'm now able to use almost the same codes as the Linux uses.The added benefit is that you can use Microsoft Visual Studio .NET.Interestingly, Trolltech has not yet offered the 3.2 version on their website.I now have access to a MacOS X Panther laptop and I started using the MacOS Xversion from the book CD. You don't need to use the fink X11 version any more. The nice thing about the Mac version is that it comes with the source codes for Qt.Index
How can I embed resources in the application?When you create your application in Qt, you load icons, toolbuttonbitmaps as files. This creates problems when you want to run your application from different location in the file system, since therelative path changes. Microsoft Visual C++ does this by building resources compiled into your application. Qt does not do this automatically. You must do the following steps described inTrolltech Doc . In my case, I needed to embed the tool button images. Here is how I did under qt3.1.2. build qembed from the source /usr/local/qt/tools/qembed. qembed --images file1 file2 file 3 > imgsrc.h Then, use it in your application as QPixmap rotateIcon; rotateIcon = QPixmap(qembed_findImage("rotate")); If you have questions, take a look at the generated file, imgsrc.h. Do I include <GL/gl.h> for an OpenGL Qt application?Usually when you use OpenGL, you do need "#include <GL/gl.h>".
This works fine for Linux Qt. Unfortunately, the half-heartedsupport by Microsoft for OpenGL
produces compiler complainingabout some definition not defined (WINGDI and APIENTRY).
On another platform (MacOSX) who likes to make incompatible, you will have to do #include <qgl.h> What is the cause for GL_STACK_OVERFLOW error?I was getting GL_STACK_OVERFLOW error and had a hard time finding the information where this error could aris. It turned out that the simplest place is glPushMatrix and glPopMatrix 1. if # of glPushMatrix > # of glPopMatrix, then GL_STACK_OVERFLOW occurs 2. if # of glPushMatrix < # of glPopMatrix, then GL_STACK_UNDERFLOW occurs Once I have this info, it was easy to find where I made the error. This is in the OpenGL documentation for glPushMatrix and glPopMatrix. Unfortunately, I could not find the description in none of the books I have on OpenGL. GL_MODEL_VIEW has at least 16 stack depth.GL_PROJECTION, and GL_TEXTURE have at least 2. How can I port Linux Qt applicaitons to MS Windows, using free Windows version?As the update states, this portion is obsolted by buying a book C++ GUI Programming with QT3. First of all, the free version for MS Windows is quite old (Qt2.3). I guess that Trolltech wants you to spend money for the latest edition. The current free Qt release for Linux side is version 3.2.2. So, don't use the features only available under Qt version 3. Otherwiseyou have to find work-arounds by yourself. You will find out whatare not available under Qt2.3 while compiling. Next, you have to make your application compilable on Visual C++ (if you do not use the Cygwin or Borland). The official way under Qt3.2.2 is to use qmake to create project and Makefile for Visual C++. I tried such a method and did not work out. Furthermore, under VC7 (.NET), nmake is taking a back-seat. I cannot find a way to make "makefile" anymore under VC7 (If you know,please let me know. it was possible under Visual C++ v.6 by clickingone of IDE menus). Therefore, I was looking for a way tocreate a project for my application. VC7 uses a XML project file (*.vcproj)and "solution" (.sln). Since I'm very lazy, I found a much easier wayto create a VC7 project. First, it is easy to create a VC6 project, since the free Windows versionof Qt comes with the VC6 project file. My application is an OpenGL application and thus took the example "gear" project file. The moral is to pick the closest example project for your application. I edited the file to change source files and header files. The .dsp file is very easy to read and edit. You will have no problem doing so. Don't forget to add .moc.cpp files to your project.Now, you have VC6 dsp file for your application. Now start VC7 (.NET)and open project... Point to your new VC6 .dsp file. VC7 will gladly convert it to the VC7 solution and project. You have to fix a bug in three QT classes under Qt 2.3. The bug is that you cannot do dllimport templated class. Templated class isinstantiated in your application. There are three header files, qdict.h, qlist.h, qintdic.h, whose Q_EXPORT should be commentedout. You start compiling files one-by-one to see what kind of problemsyour codes have. Unfortunately, some of the files won't compile. Your Qt application is that of Qt3.2.2 version, meanwhile the free Windows version is that of Qt2.3. There is a price to pay for the differences:"hand-editing" and "work-arounds". In my case, I had three problems. The first one was a generic one in that every "tr" instance generateseror. They generate weird error messages when trying to compile. After dropping all "tr"s and keep them as simple ascii quoted texts,those errors were gone. The second problem I had was that the following line could not compile: QPixmap rotateIcon = QPixmap(qembed_findImage("rotate")); This one came from the embedding resource part above. The function"qembed_findImage()" returns QImage and the compiler complainedthat it cannot convert QImage into QPixmap. I guess that this wasa new feature under Qt3. Fotunately, I was able to work aroundthe problem by the Qt2.3 function: QPixmap rotateIcon; rotateIcon.convertFromImage(qembed_findImage("rotate")); The third one is due to the MS implementation of valarray. I had to add preprocessor macro: NOMINMAX. In my application, those are the only things needed to be changed fromthe Linux version (the removing all "tr" was rather tedius even withemacs). Now you have a free MS Windows version of your application. How can I use OpenGL 1.2 features on MSWindows?Microsoft ships OpenGL Version 1.1 header files and libraries in PlatformSDK under Visual Studio .NET 2003 in Vc7 directory. I was puzzled by this and asked the Qt mailing list on howI can access OpenGL 1.2 features. The reply I got was to use video card vendors SDK. That is not necessary. After I got hold of NVIDIA NVSDK, I realized the real way: Under Windows, you have to use a weird way to have access functions of Version 1.2 or later features, rather than a simple API call. NVIDIA NVSDK has simplified this setup in a series of header files. What I needed was a multitexture and I did not need a series ofheader files. Here is how I did it in a vendor independent way. If you know exactly what is needed, then there is a simple way ;-). In a nutshell, what Microsoft wants you do is to use wglGetProcAddress to get to new functionalities. Since you are dealing with function pointers, you can use it to simplify coding between Linux (now supports OpenGL 1.3 or higher) and Windows (public API is still 1.1). #ifdef WIN32typedef void (APIENTRY *PFNGLACTIVETEXTUREARBPROC) (GLenum texture); typedef void (APIENTRY *PFNGLMULTITEXCOORD2FARBPROC) (GLenum target, GLfloat s, GLfloat t); #define GL_ARB_multitexture 1 #define GL_MAX_TEXTURE_UNITS 0x84E2 #define GL_TEXTURE0 0x84C0 #define GL_TEXTURE1 0x84C1 PFNGLACTIVETEXTUREARBPROC glActiveTexture=0; PFNGLMULTITEXCOORD2FARBPROC glMultiTexCoord2f=0; #endif Note that I intentionally named the ARB functions and constants under 1.2 to have the same name as those of 1.3 (Linux) so that the maincodes are kept the same under Linux and Windows. I then initialize function pointers if I detect the multitexturesupport: #ifdef WIN32 if (checkGLExtension("GL_ARB_multitexture")) #endif { int maxTextureUnits; glGetIntegerv(GL_MAX_TEXTURE_UNITS, &maxTextureUnits); msgTxt.sprintf("Multitexture supported with units = %d", maxTextureUnits); pParent_->statusBar()->message(msgTxt); #ifdef WIN32 glActiveTexture =(PFNGLACTIVETEXTUREARBPROC) wglGetProcAddress("glActiveTextureARB"); glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FARBPROC) wglGetProcAddress("glMultiTexCoord2fARB"); #endif where checkGLExtension() is given below. bool checkGLExtension(const std::string &extName) { if (extName.length() == 0) return false; char *extensionStr = (char*) glGetString(GL_EXTENSIONS); // initialize stringstream with the returned value std::stringstream st(extensionStr); // search through the extension string list while (st.good()) // actually "while (st)" should be enough. However, VC7 cannot take it. { string extension; st >> extension; if (extension == extName) return true; } return false; } Here is the NVIDIA SDK way to use the extension. You add the following include lines. #ifdef WIN32 #undef GL_GLEXT_PROTOTYPES #include #define GLH_EXT_SINGLE_FILE #include #include #include #include using namespace glh; Then, remove the link libraries, opengl32.lib and glu32.lib and compile at least with nvparse_mt.lib (or nvparse.lib). How can I fix the error "mr_popdef: AC_Dest undefined macro"?This is due to the fact that configure.in which is created by KDE 2.1.5 isin conflict with autoconf-2.57. Change the following line in configure.in to dnl add here all your Makefiles. This are created by configure AC_OUTPUT(Makefile mreg/Makefile mreg/docs/Makefile mreg/docs/en/Makefile ) to: dnl add here all your Makefiles. This are created by configure AC_CONFIG_FILES(Makefile) AC_CONFIG_FILES(mreg/Makefile) AC_CONFIG_FILES(mreg/docs/Makefile) AC_CONFIG_FILES(mreg/docs/en/Makefile) AC_OUTPUT This made my project in KDE 2.1.5 happy. How can I get rid of fink version of Qt?I thought that it is enough to do fink delete qt3. No, fink is not that good. I was still bothered by mkspec using mkspecs/darwin-g++. It turned out that you have to remove /sw/etc/profile.d/qt3-shlibs.csh and /sw/etc/profile.d/qt3-shlibs.sh, since these are read by/sw/bin/init.csh or /sw/bin/init.sh. These shell scripts set QTDIR as /sw and QTMAKESPEC as /sw/share/qt3/mkdpecs/darwin-g++. Updated 7/3/2004 |
Programming‎ > ‎