QString::toStdString, QString::fromStdString, and -no-stl

I use the Qt library in my day-to-day development work. I build my Qt libraries directly from the git repository and they are configured specifically for my projects. On the Mac OS X side, this is the command line I use:

The Windows one is similar:

You will notice that I am explicitly removing a whole bunch of stuff – SVG, WebKit, audio, etc.. The time it takes to build the Qt libraries is not insignificant and since I typically track the git repo, I don’t want to waste time building things I will not be using in my projects. The WebKit code takes an extraordinary amount of time to build, for example. I also don’t want to build things into the libs that I’m not going to be using for my commercial software – such as STL. One of the problems this poses, however, is how to handle build problems with other projects I want to build, for example the GUI for the open-source Cppcheck program.

For the most part the projects I’m interested in don’t use any of the capabilities I’m eliminating from my Qt build, but one option has been problematic for a couple of projects: -no-stl. This is because the projects use the functions QString::toStdString() and QString::fromStdString() which do not exist when you build Qt with the -no-stl option. While STL may be available to the source you are building, it was not compiled into the Qt libs, so this causes an error.

When I try to build Cppcheck using my own Qt build, I get errors like this:

../gui/mainwindow.cpp: In member function ‘Settings MainWindow::GetCppcheckSettings()’: ../gui/mainwindow.cpp:457: error: ‘class QString’ has no member named ‘toStdString’

../gui/threadresult.cpp: In member function ‘virtual void ThreadResult::reportOut(const std::string&)’: ../gui/threadresult.cpp:42: error: ‘fromStdString’ is not a member of ‘QString’

Solutions?

Continue reading

COLLADA Files and SketchUp Component Hierarchies

One of the formats my bloodstain pattern analysis software will export data to is COLLADA. COLLADA is an open format used to exchange 3D scene data between software packages. It is an XML format, meaning it’s readable in a text editor, but it is extremely verbose and not a simple thing to understand unless you know what you’re looking at [and even then…]. Before using it for my current work, I’d used COLLADA with an internal version of the Torque game engine at GarageGames, so I had some familiarity with the format before using it this time.

SketchUp is a powerful free modelling tool from Google. As with any software importing COLLADA, some of the concepts in the format map to concepts within the software, while others do not. One of the things that was not obvious to me when I started exporting COLLADA files for use in Google SketchUp was how to set up my COLLADA so it had hierarchical components upon import. My scenes always showed up as one monolithic component which meant that modifying parts of it to add textures or colours was not easy.

For the bloodstain analysis work, I only have to deal with simple scenes consisting of planar surfaces and lines.

SketchUp COLLADA Import Example

SketchUp COLLADA Import Example

Continue reading

Running jpegtran From a Qt Application

Continuing on with my obsession with smaller images, I thought I’d give an example of how to include jpegtran with your Qt app and how to call it using QProcess to optimize jpegs. Why do this? The use-case I had was that I was downloading images from the net from within my application and I wanted to ensure that they were optimized. I could have read them in and used my modifications to QImageWriter & co. to write them back out, but we are dealing with JPEG which is a lossy format, so I wanted a lossless way to optimize the images.

Continue reading

qmake and the Info.plist File

I use the Qt library and qmake to build my bloodstain pattern analysis software. qmake is a great tool for cross-platform development because it lets you use one relatively succinct description [a .pro file] to generate Xcode projects, MSVC projects, and makefiles. On the Mac OS X side of things, I use one qmake .pro file to generate three xcode projects: release, beta, and demo. My directory structure looks like this:

Example File Structure

Example File Structure

Overall this works well, but there’s an issue with the Info.plist file.

Continue reading

QImageWriter and Writing JPEGs

If you are using the QImageWriter class in Qt to write JPEG files, you may have noticed that it creates large files.

For example, saving out a capture of a window in my app resulted in a 332 kB file. If I run that through ImageOptim [mentioned previously], this is reduced to 266 kB. Huh? What’s happening here?

Digging into the code, I looked at what jpegtran [which is what ImageOptim is running] did to reduce file size. It turns out there are two options you can turn on in libjpeg to reduce file size when writing out JPEGs: optimize and progressive scan. These are both lossless operations, so by turning both of these options on we can reduce the size of the image files without sacrificing any quality.

If I turn on just the optimize option, the file size reduces to 287 kB. Turning both optimize and progressive on reduces the files size to… 266 kB – the same as ImageOptim.

I should also note that writing PNGs using QImageWriter is almost useless given the size of the files it produces [at 100% quality]. The same window capture I mention above results in a 6.6 MB PNG! This can be reduced to a much more manageable 242 kB if you run it through ImageOptim. The problem is, unlike JPEG, the time to optimize a PNG is not trivial, so even if there are switches to do something similar, the time it takes to optimize would result in long delays writing out the PNG file. I haven’t fully investigated this, so there may yet be a solution.

To handle the JPEG issue, I filed a Qt report and patch: Support additional JPEG write options: ‘optimize’ and ‘progressive’ [QTBUG-20075].

The patch modifies the following files:

  • src/gui/image/qimageiohandler.cpp
  • src/gui/image/qimageiohandler.h
  • src/gui/image/qimagewriter.cpp
  • src/gui/image/qimagewriter.h
  • src/gui/image/qjpeghandler.cpp

It adds two options to the QImageWriter class: ImageOption::Optimize and ImageOption::Progressive. It is used like this:

Magic! Smaller JPEG files for free. I hope this patch will eventually make its way into the release version of Qt.

I can’t see any reason why the optimize option within libjpeg defaults to false in the first place – any ideas?

(19 Jan 2015): I submitted a patch for this which has been merged into the Qt codebase. This fix will be part of Qt 5.5.

QSignalMapper Example

Qt is a great development framework. I’ve been using it for years and I’m still discovering new & improved ways to do things. For example, I had a rather clunky bit of code to put menu items in the help menu which would open up various pages on my website.

myMainWindow.h

myMainWindow.cpp

Wow. That’s chunky code. Any additional menu items required a declaration of another one line function which of course meant modifying the header and the cpp file. Messy.

Then I discovered QSignalMapper which let me tie a QString to a given QAction so I would only need one slot to handle any URL opening.

Continue reading