<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>LYNXLINE</title>
	<atom:link href="http://lynxline.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://lynxline.com</link>
	<description>Professional Software Development Services using Qt frameworks</description>
	<lastBuildDate>Wed, 22 Feb 2012 18:20:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Stack vs Heap, Pimpl, performance</title>
		<link>http://lynxline.com/stack-vs-heap-pimpl-performance/</link>
		<comments>http://lynxline.com/stack-vs-heap-pimpl-performance/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 23:14:20 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[Research]]></category>

		<guid isPermaLink="false">http://lynxline.com/?p=470</guid>
		<description><![CDATA[This post is mostly about C++ but because it involves practices often used with Qt programming too, I tagged it with Qt. Also should be interesting for C++ gurus So, you know that Qt uses Pimpl (Private Implementation or Opaque pointer) which is very effective mechanism to keep binary compatibility between Qt versions. I use [...]]]></description>
			<content:encoded><![CDATA[<p>This post is mostly about C++ but because it involves practices often used with Qt programming too, I tagged it with Qt. Also should be interesting for C++ gurus <img src='http://lynxline.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>So, you know that Qt uses Pimpl (<a href="http://www.qtcentre.org/wiki/index.php?title=Private_implementation" title="Private Implementation" target="_blank">Private Implementation</a> or <a href="http://en.wikipedia.org/wiki/Opaque_pointer#C.2B.2B" title="Opaque pointer" target="_blank">Opaque pointer</a>) which is very effective mechanism to keep binary compatibility between Qt versions. I use it very often too, but mostly not because of binary compatibility needs, but because of possibility of hiding internals and implementations especialities into cpp files. </p>
<p>And there is something even more important, such practice allows to avoid including 3-rd party headers from your headers &#8211; your API &#8211; you know, it can often happen that you need some &#8220;utility&#8221; api, but because of including the header it leads to bring bunch of unexpected includes coming from this &#8220;utility&#8221;. Even worse, these 3-rd party headers that you probably can not even control, bring unexpected defines, pragmas etc that can makes you puzzled for hours to understand <em>why?, how? and in which order?</em> it conflicts with your coding.</p>
<p>Using <em>d</em> pointer (Private Implementation) allows really avoid including these unneeded headers, but recently in huge project it makes me to think about performance issues.<span id="more-470"></span> Usually it looks like:</p>
<pre  class="brush:cpp">
// HEADER *****************
class DynObj {
public:
    DynObj();
    virtual ~DynObj();

private:
    Private * d;
};

// SOURCE *****************
class DynObj::Private {
public:
    //internals
};

DynObj::DynObj() { d = new Private; }
DynObj::~DynObj() { delete d; }
</pre>
<p>It is very effective for all advantages that I described above except one: if this is expected to be some lightweight object then when you instantiate one you actually get two memory allocation operations: one is for object itself and second one for the <em>Private</em> object. And if you have control for first allocation &#8211; stack or heap, you do not have control of second one &#8211; always heap.</p>
<p>In my case I used billions of these objects as parameters of methods, return values, local variables etc. Problem is that even if you expect that the object will be allocated in stack, still due to <em>Private</em> sub-object it will request &#8220;new&#8221; and &#8220;delete&#8221; so heap is involved in any case, but surely using just stack should be faster. How much? Let&#8217;s do some lab to measure.</p>
<p>Lab definition:</p>
<ol>
<li>Define two classes, one is just standard class using <em>d-pointer</em>, second should be fully allocated in stack if needed</li>
<li>Still both should use idea of <em>Private Implementation</em>, so need some tricks for second class</li>
<li>Measure time spent on allocation of objects of two types</li>
</ol>
<p>So, we would like to have <em>Private Implementation</em>, but use kind of <em>d-pointer</em>, so when object allocation requests memory it should give enough amount of bytes with reserved space to fit <em>Private</em> object later. Of course we can just define <em>quint8 d_bytes[d_size];</em>, but compiler can not calculate d_size without knowing details of implementation of <em>Private</em>, but it breaks idea of closing internals into cpp only.</p>
<p>We can do just some tricking, we declare some magic number <em>static const int d_size;</em>, but in cpp we use static assert to compare this magic number with real size of <em>Private</em>.</p>
<p>Code to do such static assert is:</p>
<pre  class="brush:cpp">
namespace static_assert {
template &lt;bool> struct is_fail;
template &lt;> struct is_fail&lt;true> { enum { value = 1 }; };
}

template &lt;int def,int real>
struct check_d_size : ::static_assert::is_fail&lt;(bool)(def == real)> {};
</pre>
<p>Then in constructor we can place code:</p>
<pre  class="brush:cpp">
check_d_size&lt;d_size,sizeof(Private)>();
</pre>
<p>And on compilation we will get error like that:<br />
<code>../cpp-dyn-vs-stack/main.cpp: In instantiation of 'check_d_size<31, 32>':</code></p>
<p>Now easy to know right magic number.<br />
BTW: Surely <strong>totally unportable</strong> trick! But fine for our lab and measurements.</p>
<p>Another issue: we have enough memory reserved in object, but we need initialize it in right way &#8211; use constructor, but with ready memory. Like that:</p>
<pre  class="brush:cpp">
class StackObj {
public:
    StackObj() {
        check_d_size&lt;d_size,sizeof(Private)>();
        d = new(d_bytes) Private;
    }
    virtual ~StackObj() { d->~Private(); }
private:
    class Private {
    public:
        inline void * operator new(size_t, quint8 * mem) { return mem; }
        ...
    };
private:
    Private * d;
    static const int d_size = 32;
    quint8 d_bytes[d_size];
};
</pre>
<p>Now if our StackObj is placed in stack then 1. appropriate memory is reserved, 2. <em>Private</em> sub-object is initialized in right way with all constructors of internals etc. And we still can keep implementation with internals in cpp and leave only API in header without 3-rd party includes. </p>
<p>Time to measures: </p>
<ul>
<li>allocate 100,000 objects in stack using heap for <em>Private</em>: <strong>24 msecs</strong></li>
<li>allocate 100,000 objects in stack using stack for <em>Private</em>: <strong>8 msecs</strong></li>
</ul>
<p>Wow! 3-times difference.<br />
So, keep track what you can put in stack and what in heap if you count your computing time!</p>
<p>Full listing:</p>
<pre  class="brush:cpp">
#include &lt;iostream>
#include &lt;string>

#include &lt;QTime>
#include &lt;QDebug>

using namespace std;

class DynObj {
public:
    DynObj() { d = new Private; }
    virtual ~DynObj() { delete d; }

private:
    class Private {
    public:
        int i;
        int j;
        DynObj * p;
        std::string str;
        class Check {
        public: Check() { static bool b=true; if (b) { qDebug() << "ok new dyn"; b = !b; } }
               ~Check() { static bool b=true; if (b) { qDebug() << "ok del dyn"; b = !b; } }
        } chk;
    };
    Private * d;
};

namespace static_assert {
template &lt;bool> struct is_fail;
template &lt;> struct is_fail&lt;true> { enum { value = 1 }; };
}

template &lt;int def,int real>
struct check_d_size : ::static_assert::is_fail&lt;(bool)(def == real)> {};

class StackObj {
public:
    StackObj() {
        check_d_size&lt;d_size,sizeof(Private)>();
        d = new(d_bytes) Private;
    }
    virtual ~StackObj() { d->~Private(); }

private:
    class Private {
    public:
        inline void * operator new(size_t, quint8 * mem) { return mem; }

        int i;
        int j;
        DynObj * p;
        std::string str;

        class Check {
        public: Check() { static bool b=true; if (b) { qDebug() << "ok new stack"; b = !b; } }
               ~Check() { static bool b=true; if (b) { qDebug() << "ok del stack"; b = !b; } }
        } chk;
    };
    Private * d;
    static const int d_size = 32;
    quint8 d_bytes[d_size];
};

int main()
{
    QTime t = QTime::currentTime();

    { DynObj ar_dyn[100000]; }

    qDebug() << "use dyn, call time, msecs" << t.msecsTo(QTime::currentTime());

    t = QTime::currentTime();

    { StackObj ar_stack[100000]; }

    qDebug() << "use stack, call time, msecs" << t.msecsTo(QTime::currentTime());

    return 0;
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://lynxline.com/stack-vs-heap-pimpl-performance/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Jongling Qt models 2, Composition Gem</title>
		<link>http://lynxline.com/jongling-qt-models-2-composition-gem/</link>
		<comments>http://lynxline.com/jongling-qt-models-2-composition-gem/#comments</comments>
		<pubDate>Mon, 19 Sep 2011 12:45:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Models]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[Research]]></category>

		<guid isPermaLink="false">http://lynxline.com/?p=437</guid>
		<description><![CDATA[We are back to models again . In Qt you may find a lot of flexibilities for Model-View programming. Especially due to proxies to do filtering, sorting or even rearranging data (see Jongling Qt models) to be organized in any way that is good for you. You can have one data source model which you [...]]]></description>
			<content:encoded><![CDATA[<p>We are back to models again <img src='http://lynxline.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> . In Qt you may find a lot of flexibilities for Model-View programming. Especially due to proxies to do filtering, sorting or even rearranging data (see <a href="http://lynxline.com/jongling-qt-models/" title="Jongling Qt models">Jongling Qt models</a>) to be organized in any way that is good for you. You can have one data source model which you then split in &#8220;flows&#8221; of data with chains of proxy models which have ends at views. For example friend of mine found that it is very effective to have one single model for all data loaded which then goes in 3-4 chains of about 15 proxy models in totals. Why so much? &#8211; Every proxy is as much simple operation as possible, for example: filter, ungroup, transpose, etc. Each simple operation much easier to implement, debug and prove effectiveness. But by joining them in chain you can make any complicated operations. You have to track complexity that you get at the end of chain &#8211; i.e. sorting proxy will add O(n*log(n)), but if you make filtering before sorting, then it goes faster.</p>
<p>But you may encounter one area which is totally uncovered &#8211; there is no way of joining of models into one composition proxy model. So I would like to present some &#8220;Gem&#8221; for Qt model-view programmers: RowsJoinerProxy class. It does very simple thing: join all top level rows from first source model, second, etc. It does not affect children, so all hierarchies of source models are kept. For root columns it uses qMax(columCount() of roots of source models). Rows inserts, rows removals, data changes of source models are recognized and mapped. Column operations are not supported at the moment, so I may update it later. Inserting/Removing source model from proxy makes model reset, though it can be improved later to do just rows removal.</p>
<p>Files:<br />
<a href="http://lynxline.com/wp-content/uploads/2011/09/RowsJoinerProxy.h">RowsJoinerProxy.h</a><br />
<a href="http://lynxline.com/wp-content/uploads/2011/09/RowsJoinerProxy.cpp">RowsJoinerProxy.cpp</a></p>
]]></content:encoded>
			<wfw:commentRss>http://lynxline.com/jongling-qt-models-2-composition-gem/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Submiting a Qt App to Mac App Store</title>
		<link>http://lynxline.com/submiting-to-mac-app-store/</link>
		<comments>http://lynxline.com/submiting-to-mac-app-store/#comments</comments>
		<pubDate>Wed, 29 Jun 2011 19:11:08 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[MacAppStore]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[QtSpeech]]></category>
		<category><![CDATA[TogMeg]]></category>
		<category><![CDATA[TTS]]></category>

		<guid isPermaLink="false">http://lynxline.com/?p=390</guid>
		<description><![CDATA[Maybe you already thought about creation a Qt application for Mac App Store or submitting an existing one. While I am on vacations I made a probe of such possibility &#8211; you may know that Apple and Nokia developing now different ecosystems of languages/libraries and you may expect to have troubles of bypassing Qt application [...]]]></description>
			<content:encoded><![CDATA[<p>Maybe you already thought about creation a Qt application for Mac App Store or submitting an existing one. While I am on vacations I made a probe of such possibility &#8211; you may know that Apple and Nokia developing now different ecosystems of languages/libraries and you may expect to have troubles of bypassing Qt application into Mac App Store. Anyway I found that it is not so complicated as expected, though it took time to do all preparations, my application passed and was published in store with first attempt.</p>
<p>For long time I had one application in my attic. It was an interesting experiment for studying and remembering foreign words. This application do kind of training by repeating words and force you to type correct spelling while application pronounce it to you using TTS (surely you need high-quality voice engine &#8211; I used voices from Infovox iVox). That was pretty effective and helped me a lot for studying new words and forming active vocabulary for Norwegian. Because of hearing, reading and typing it makes very effective associations in your brains. The application is cross-platform and requires only QtGui, QtXml and QtCore, also qt plugins are not need.</p>
<p><center><a href="http://lynxline.com/wp-content/uploads/2011/06/TogMeg-Screenshot-1.png"><img src="http://lynxline.com/wp-content/uploads/2011/06/TogMeg-Screenshot-1-300x238.png" alt="" title="TogMeg-Screenshot-1" width="300" height="238" class="alignnone size-medium wp-image-429" /></a></center><br />
<span id="more-390"></span></p>
<p>First I worked on adjustments of widgets and look-and-feel to have app closer to Mac style. It wasn&#8217;t complicated because on each release Nokia improves drawing of widgets to have it very close to native views. You can find differences in user interface if you know especialities.</p>
<p>Then application (bundle) was build with inclusion of all required libs as private frameworks. I got too much for such small application — about 60MB. For me it is too heavy and I decided to make it smaller. Also after checking Qt forums I found that some patches are required for Qt to get a ticket into store.</p>
<p>It was chosen Carbon version of Qt because I found some glitches in GUI when used Cocoa &#8211; so I decided not to spend time on it. Then disabled everything that is not needed in configure, also used 10.5 sdk and only 32 bit:</p>
<pre  class="brush:bash">
./configure -carbon -fast -no-qt3support -no-xmlpatterns -no-multimedia -no-audio-backend -no-phonon -no-phonon-backend -no-svg -no-webkit -no-javascript-jit -no-script -no-scripttools -no-declarative -no-openssl -arch "x86" -sdk "/Developer/SDKs/MacOSX10.5.sdk" -no-exceptions
</pre>
<p>I got about 30MB for Frameworks. But Framework folders can be downsized — no need for debug versions of libs, no need for header files because frameworks are private. Because I used copying of Frameworks using <em>QMAKE_POST_LINK</em>, it looks like this:</p>
<pre  class="brush:bash">
QMAKE_POST_LINK = \
mkdir -p $${BUNDLETARGET}/Contents/Frameworks; \
cp -R $${QTFRAMEWORKSPATH}/QtCore.framework \
$${QTFRAMEWORKSPATH}/QtGui.framework \
$${QTFRAMEWORKSPATH}/QtXml.framework \
$${BUNDLETARGET}/Contents/Frameworks; \
...
\
strip $(TARGET); \
strip -x $${BUNDLETARGET}/Contents/Frameworks/QtCore.framework/Versions/4/QtCore; \
strip -x $${BUNDLETARGET}/Contents/Frameworks/QtGui.framework/Versions/4/QtGui; \
strip -x $${BUNDLETARGET}/Contents/Frameworks/QtXml.framework/Versions/4/QtXml; \
\
rm -rf `find $${BUNDLETARGET} -name "*.prl"`; \
rm -rf `find $${BUNDLETARGET} -name "*.lproj"`; \
rm -rf `find $${BUNDLETARGET} -name "*_debug*"`; \
rm -rf `find $${BUNDLETARGET} -name "Headers"`; \
\
otool -L $(TARGET); \
otool -L $${BUNDLETARGET}/Contents/Frameworks/QtCore.framework/Versions/4/QtCore; \
otool -L $${BUNDLETARGET}/Contents/Frameworks/QtGui.framework/Versions/4/QtGui; \
otool -L $${BUNDLETARGET}/Contents/Frameworks/QtXml.framework/Versions/4/QtXml; \
\
echo "Ok"
</pre>
<p>Result — 12MB, in Mac App Store – just 5.3MB. This is great just for small application which is based on non-native GUI frameworks.</p>
<p>So we resolved size issue, now it is time to get Qt ready to pass examination and be ready for store.</p>
<p>First — app should keep own data in <em>~/Library/Application Support/com.organization.appname</em>, so we download patch <a href="http://bugreports.qt.nokia.com/secure/attachment/23529/mac-app-store-cache-location.diff">mac-app-store-cache-location.diff</a>. After applying it, when using <em>QDesktopServices::storageLocation()</em> we get right path to location where to keep app/user data.</p>
<p>Second — Qt apps always read and write <em>~/Library/Preferences/com.nokia.qt.plist</em>. You can not disable it due to need of common settings of Qt Applications. But Apple has restrictions for applications not to write settings of other applications. So we download second patch for Qt — <a href="http://bugreports.qt.nokia.com/secure/attachment/23530/mac-settings-in-app-area.diff">mac-settings-in-app-area.diff</a>, and in <em>main()</em> in very beginning  add a call: <em>qt_force_trolltech_settings_to_app_area(true);</em></p>
<p>Also there are two patches — first one is for removal <em>Hide/Show All</em> from application menu, but I found this patch later, though my app passed control without it, and second one is for SQLite — but I did not study this one (no need for my app).</p>
<p>Frameworks should be adjusted to have them referenced to each other using <em>@executable_path</em>. You can see it easily by otool utility:</p>
<pre  class="brush:bash">
$ otool -L QtGui.framework/QtGui
QtGui.framework/QtGui:
/usr/local/Trolltech/Qt-4.7.3/lib/QtGui.framework/Versions/4/QtGui (compatibility version 4.7.0, current version 4.7.3)
/usr/local/Trolltech/Qt-4.7.3/lib/QtCore.framework/Versions/4/QtCore (compatibility version 4.7.0, current version 4.7.3)
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon (compatibility version 2.0.0, current version 136.0.0)
...
</pre>
<p>Add this to <em>QMAKE_POST_LINK</em>:</p>
<pre  class="brush:bash">
install_name_tool -id @executable_path/../Frameworks/QtCore.framework/Versions/4/QtCore \
$${BUNDLETARGET}/Contents/Frameworks/QtCore.framework/Versions/4/QtCore; \
install_name_tool -id @executable_path/../Frameworks/QtGui.framework/Versions/4/QtGui \
$${BUNDLETARGET}/Contents/Frameworks/QtGui.framework/Versions/4/QtGui; \
install_name_tool -id @executable_path/../Frameworks/QtXml.framework/Versions/4/QtXml \
$${BUNDLETARGET}/Contents/Frameworks/QtXml.framework/Versions/4/QtXml; \
...
+and same for other references
</pre>
<p>Now everything is fine:</p>
<pre  class="brush:bash">
otool -L QtGui.framework/QtGui
QtGui.framework/QtGui:
@executable_path/../Frameworks/QtGui.framework/Versions/4/QtGui (compatibility version 4.7.0, current version 4.7.3)
@executable_path/../Frameworks/QtCore.framework/Versions/4/QtCore (compatibility version 4.7.0, current version 4.7.3)
/System/Library/Frameworks/Carbon.framework/Versions/A/Carbon (compatibility version 2.0.0, current version 136.0.0)
...
</pre>
<p>Now just by copying .app bundle onto another Mac without developer tools and Qt your App should start without problems.</p>
<p>Also you need to sign your app by your signature(certificate) as Mac developer. You have to get such certificate from developer.apple.com, pay $99 for year subscription if you haven&#8217;t done it yet.</p>
<pre  class="brush:bash">
/usr/bin/codesign -f -s 3rd\ Party\ Mac\ Developer\ Application:\ Firstname\ Lastname $${BUNDLETARGET}; \
</pre>
<p>and add this to &#8220;pro&#8221; file too.</p>
<p>But for submitting the application into App Store, I had to start Xcode, build it in dsym+dwarf mode, make it signed, added prepared Frameworks by «New Build Phase -> New Copy Files Build Phase». Everything was tested with <em>otool</em> to see all dependencies, checked on another Mac and got ready to send into App Store (<em>If you know how to do all such stuff by scripts please let me know &#8211; prefer to do everything in Qt Creator</em>).</p>
<p>Summary —<br />
1. It is not so complicated as for first sight.<br />
2. Apple is okay to accept Qt apps, just need to apply some patches to Qt.<br />
3. Size of Qt App (bundle) is small enough (maybe if you include several resources into app bundle then size of Qt frameworks may become a minor part).</p>
<p>Result — <a href="http://itunes.apple.com/us/app/togmeg/id445287955">http://itunes.apple.com/us/app/togmeg/id445287955</a></p>
<p>References:<br />
Main source of information — <a href="http://bugreports.qt.nokia.com/browse/QTBUG-16549">http://bugreports.qt.nokia.com/browse/QTBUG-16549</a></p>
]]></content:encoded>
			<wfw:commentRss>http://lynxline.com/submiting-to-mac-app-store/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>QtSpeech, say &#8220;Hello World!&#8221;</title>
		<link>http://lynxline.com/qtspeech-say-hello-world/</link>
		<comments>http://lynxline.com/qtspeech-say-hello-world/#comments</comments>
		<pubDate>Thu, 10 Feb 2011 14:14:40 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[QtSpeech]]></category>
		<category><![CDATA[Research]]></category>
		<category><![CDATA[TTS]]></category>

		<guid isPermaLink="false">http://lynxline.com/?p=313</guid>
		<description><![CDATA[I am glad to announce new small project that got first release &#8211; QtSpeech. This is library providing Qt-like interface to system TTS (text-to-speech) engines to allow your application to say &#8220;Hello World!&#8221;. Current API is very simple. First you need to include &#60;QtSpeech>. Then if your application just needed to say something synchronously (execution [...]]]></description>
			<content:encoded><![CDATA[<p>I am glad to announce new small project that got first release &#8211; <a href="http://gitorious.org/qt-speech">QtSpeech</a>.<br />
This is library providing Qt-like interface to system TTS (text-to-speech) engines to allow your application to say &#8220;Hello World!&#8221;.</p>
<p><span id="more-313"></span></p>
<p>Current API is very simple.<br />
First you need to include &lt;QtSpeech>. Then if your application just needed to say something synchronously (execution will wait in the point until speech is finished) you can use such code:</p>
<pre  class="brush:cpp">
#include &lt;QtSpeech>
...
QtSpeech voice;
voice.say("Hello World!");
</pre>
<p>If you would like to do this in asynchronous way (so your application is not blocked meanwhile) just use tell() call:</p>
<pre  class="brush:cpp">
QtSpeech * voice = new QtSpeech(this);
voice->tell("Hello asynchronous world!");
</pre>
<p>If you need to invoke a slot at the end, use:</p>
<pre  class="brush:cpp">
voice->tell("Hello!", this, SLOT(onSpeechFinished()));
</pre>
<p>Also you have possibility to get list of voices and choose voice from available in your system:</p>
<pre  class="brush:cpp">
QtSpeech::VoiceNames vs = QtSpeech::names()
</pre>
<p>Current implementation support <strong>Windows</strong> using SAPI and <strong>Mac</strong>. I have plans to extend API to include more functionality but will try to choose what is common on all platforms.</p>
<p>Link to repository in Gitorius: <a href="http://gitorious.org/qt-speech">http://gitorious.org/qt-speech</a></p>
<p><strong>UPDATE</strong>: Unix/Linux got implementation too! Based on Festival, so only English at the moment, but it is a great start to have TTS working in Qt applications too in Linux systems!</p>
]]></content:encoded>
			<wfw:commentRss>http://lynxline.com/qtspeech-say-hello-world/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>SuperHybrids part 2, now Qt + PySide</title>
		<link>http://lynxline.com/superhybrids-part-2-now-qt-pyside/</link>
		<comments>http://lynxline.com/superhybrids-part-2-now-qt-pyside/#comments</comments>
		<pubDate>Mon, 04 Oct 2010 09:24:27 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Embedding]]></category>
		<category><![CDATA[Hybrids]]></category>
		<category><![CDATA[PySide]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[Research]]></category>

		<guid isPermaLink="false">http://lynxline.com/?p=232</guid>
		<description><![CDATA[I would like to return to a topic that I opened few months ago &#8211; about creation of &#8220;hybrid&#8221; applications consisting of one part of c++ code and another part is python based, plus both part access each other with Qt-like Api, so they understand QString, etc and can exchange qt signals between those two [...]]]></description>
			<content:encoded><![CDATA[<p>I would like to return to a topic that I opened few months ago &#8211; about creation of &#8220;<strong>hybrid</strong>&#8221; applications consisting of one part of c++ code and another part is python based, plus both part access each other with Qt-like Api, so they understand QString, etc and can exchange qt signals between those two parts. Even more, c++ part of application can generate python qt-like code to execute during <em>runtime</em>, he-he&#8230; In <a href="qt-python-superhybrids">my previous post</a> I explained how to implement this based on PyQt libraries. Also it can be interpreted as embedding PySide into Qt applications.</p>
<p>I got a lot of questions about this ideas, but one of frequent questions was about doing same with PySide. Well, PySide is <strong>LGPL</strong> so this makes the framework applicable for much more projects. So, let&#8217;s have a try of doing same but with <strong>PySide</strong> now.</p>
<p><span id="more-232"></span></p>
<p>First, I tried binary packages, but looks like they do not have generatorrunner executable included and other stuff for making bindings for Qt-like libraries &#8211; let&#8217;s wish for maintainers to include them. So, we need to build it manually. Needed CMake, installed Qt Frameworks, Python.</p>
<p>So I followed instructions listed on <a href="http://www.pyside.org/docs/pyside/howto-build/index.html">PySide web site</a> and got it after hour-two. Let&#8217;s better show step-by-step for sure (I have done it on Mac OS 10.6, Qt 4.7 binaries from Nokia, Python 2.6):</p>
<pre  class="brush:shell">
# git clone git://gitorious.org/pyside/apiextractor.git
# cd apiextractor
# mkdir build &#038;&#038; cd build
# cmake .. &#038;&#038; make &#038;&#038; make install &#038;&#038; cd ../..
#
# git clone git://gitorious.org/pyside/generatorrunner.git
# cd generatorrunner
# mkdir build &#038;&#038; cd build
# cmake .. &#038;&#038; make &#038;&#038; make install &#038;&#038; cd ../..
#
# git clone git://gitorious.org/pyside/shiboken.git
# cd shiboken
# mkdir build &#038;&#038; cd build
# cmake .. &#038;&#038; make &#038;&#038; make install &#038;&#038; cd ../..
#
# git clone git://gitorious.org/pyside/pyside.git
# cd pyside
# mkdir build &#038;&#038; cd build
# cmake .. &#038;&#038; make &#038;&#038; make install &#038;&#038; cd ../..
</pre>
<p>Now we have additionaly generatorrunner and typesystems needed for making wrappings to c++ mudules.</p>
<p>Let&#8217;s return to our hybrid application &#8211; create next folder structure:</p>
<pre  class="brush:shell">
HybridApp/
 |-data/
 |    |-global.h
 |    |-typesystem.xml
 |-hybrid/
 |    |-MainWindow.h
 |    |-MainWindow.cpp
 |    |-hybrid.pro
 |-hybridpy/
 |    |-hybridpy.pro
 |-build.sh
 |-Main.py
 </pre>
<p>Let&#8217;s explain:</p>
<ul>
<li>Folder <strong>hybrid</strong> contains c++ part of application which is built into shared lib.</li>
<li>Folder <strong>hybridpy</strong> contains wrapping for c++ part &#8211; it builds Python module which will be imported into python part of application.</li>
<li>Folder <strong>data</strong> contains definition of typesystem used in c++ part. This is Xml file which describes types of used objects and their especialities when converting into python objects. More details about typesystems &#8211; on <a href="http://www.pyside.org/docs/shiboken/tutorial/typesystemcreation.html">pyside page</a> with following links.</li>
</ul>
<p>Now we go into <strong>hybrid</strong> folder and create c++ part of hybrid. First let&#8217;s do it as c++ only application with own main() methon.</p>
<p>hybrid/hybrid.pro</p>
<pre  class="brush:perl">
TEMPLATE = app
CONFIG += qt
QT += core gui

UI_DIR = build
RCC_DIR = build
MOC_DIR = build
OBJECTS_DIR = build

HEADERS += MainWindow.h
SOURCES += MainWindow.cpp Main.cpp
</pre>
<p>hybrid/Main.cpp:</p>
<pre  class="brush:cpp">
#include &lt;QtGui>
#include "MainWindow.h"
int main(int argc, char ** argv) {
    QApplication app(argc, argv);
    MainWindow window;
    window.resize(1000,700);
    window.show();
    return app.exec();
}
</pre>
<p>hybrid/MainWindow.h:</p>
<pre  class="brush:cpp">
#ifndef MainWindow_H
#define MainWindow_H

#include &lt;QMainWindow>
class QPushButton;
class QGraphicsView;
class QGraphicsScene;
class QPlainTextEdit;

class MainWindow : public QMainWindow { Q_OBJECT
public:
    MainWindow(QWidget * parent = 0L);
    virtual ~MainWindow();

signals:
    void runPythonCode(QString);

private slots:
    void runPythonCode();

public:
    QGraphicsView * viewer;
    QGraphicsScene * scene;
    QPlainTextEdit * editor;
    QPushButton * pb_commit;
};
#endif // MainWindow_H
</pre>
<p>hybrid/MainWindow.cpp:</p>
<pre  class="brush:cpp">
#include &lt;QtGui>
#include "MainWindow.h"

MainWindow::MainWindow(QWidget * parent):QMainWindow(parent) {
    QSplitter * splitter = new QSplitter;
    setCentralWidget(splitter);

    QWidget * editorContent = new QWidget;
    splitter->addWidget(editorContent);

    QVBoxLayout * layout = new QVBoxLayout;
    editorContent->setLayout(layout);

    editor = new QPlainTextEdit;
    layout->addWidget(editor);

    pb_commit = new QPushButton(tr("Commit"));
    connect(pb_commit, SIGNAL(clicked()),
            this, SLOT(runPythonCode()));
    layout->addWidget(pb_commit);

    scene = new QGraphicsScene(this);
    viewer = new QGraphicsView;
    viewer->setScene(scene);
    splitter->addWidget(viewer);

    splitter->setSizes(QList&lt;int>() << 400 << 600);
}

MainWindow::~MainWindow() {;}

void MainWindow::runPythonCode() {
    emit runPythonCode(editor->toPlainText());
}
</pre>
<p>As result we have a window with editor (left) and canvas (right):<br />
<img src="http://lynxline.com/wp-content/uploads/2010/07/PyQtHybrid-1.png" alt="MainWindow" /></p>
<p>Now it is time to to turn it into PySide-based application. We are going to:</p>
<ul>
<li>Change c++ part to dynamic library</li>
<li>Create wrappings for MainWindow class</li>
<li>Make Main.py instead of C main() routine</li>
</ul>
<p>For first point we just change TEMPLATE to lib, exclude Main.cpp, and build the shared lib. Also set TARGET to have shared libraries in root folder of HybridApp</p>
<p>hybrid/hybrid.pro:</p>
<pre  class="brush:perl">
TEMPLATE = lib
TARGET = ../Hybrid
CONFIG += qt
QT += core gui

UI_DIR = build
RCC_DIR = build
MOC_DIR = build
OBJECTS_DIR = build

HEADERS += MainWindow.h
SOURCES += MainWindow.cpp
</pre>
<p>As result you should get <strong>libHybrid.dylib</strong> in root of our project (HybrydApp)</p>
<p>Now it is time to generate wrappings for c++ part to use in python. The generation is made by <strong>build.sh</strong> script in root of project. (Actually it builds everything &#8211; both c++ and wrapping parts)</p>
<p>build.sh</p>
<pre  class="brush:shell">
#!/bin/sh

cd hybrid
qmake
make
cd ..

cd hybridpy

QTGUI_INC=/Library/Frameworks/QtGui.framework/Versions/4/Headers
QTCORE_INC=/Library/Frameworks/QtCore.framework/Versions/4/Headers
QTTYPESYSTEM=/usr/local/share/PySide/typesystems

generatorrunner --generatorSet=shiboken \
    ../data/global.h \
    --include-paths=../hybrid:$QTCORE_INC:$QTGUI_INC:/usr/include \
    --typesystem-paths=../data:$QTTYPESYSTEM \
    --output-directory=. \
    ../data/typesystem.xml

qmake
make
cd ..

rm -rf PyHybrid.so
ln -s libPyHybrid.dylib PyHybrid.so
</pre>
<p>You see that this is just one call of <strong>generatorrunner</strong> plus you provide paths for Qt includes, qt typesystem and your typesystem. Then in folder <strong>hybridpy</strong> we with qmake build the python module.</p>
<p>Listing of our <strong>typesystem.xml</strong> and <strong>global.h</strong>:</p>
<p>data/typesystem.xml</p>
<pre  class="brush:xml">
&lt;?xml version="1.0"?>
&lt;typesystem package="PyHybrid">
    &lt;load-typesystem name="typesystem_core.xml" generate="no"/>
    &lt;load-typesystem name="typesystem_gui.xml" generate="no"/>
    &lt;object-type name="MainWindow"/>
&lt;/typesystem>
</pre>
<p>data/global.h (fyi: more details about global.h &#8211; <a href="http://www.pyside.org/docs/shiboken/tutorial/globalheader.html">here</a>)</p>
<pre  class="brush:cpp">
#undef QT_NO_STL
#undef QT_NO_STL_WCHAR

#ifndef NULL
#define NULL    0
#endif

#include &lt;MainWindow.h>
</pre>
<p>And pro file for building python module:</p>
<p>hybridpy/hybridpy.pro</p>
<pre  class="brush:perl">
TEMPLATE = lib
QT += core gui

INCLUDEPATH += hybrid
INCLUDEPATH += ../hybrid

INCLUDEPATH += /usr/include/python2.6
INCLUDEPATH += /usr/local/include/shiboken
INCLUDEPATH += /usr/local/include/PySide
INCLUDEPATH += /usr/local/include/PySide/QtCore
INCLUDEPATH += /usr/local/include/PySide/QtGui

LIBS += -ldl -lpython2.6
LIBS += -lpyside
LIBS += -lshiboken
LIBS += -L.. -lHybrid

TARGET = ../PyHybrid

SOURCES += \
    pyhybrid/pyhybrid_module_wrapper.cpp \
    pyhybrid/mainwindow_wrapper.cpp \
</pre>
<p>You can mention that most of used paths of python headers and qt headers can be extracted from utils like <em>pkg-config</em> etc &#8211; that&#8217;s true, but I showed exact paths intentionally just for demoing what is really included. Also, of course you can do it all with <em>cmake</em>, but I made a choice for <em>qmake pro files</em> to have better (plain) presentation of used files and logic.</p>
<p>Looks complete &#8211; if you just run build.sh you will get PyHybrid.so &#8211; python module.<br />
Everything is ready, time to connect both parts in Main.py script:</p>
<p>Main.py</p>
<pre  class="brush:python">
import sys
from PySide.QtCore import *
from PySide.QtGui import *
from PyHybrid import *

class RunScript(QObject):
    def __init__(self, mainWindow):
        QObject.__init__(self)
        self.mainWindow = mainWindow

    def runScript(self, script):
        mainWindow = self.mainWindow
        exec(str(script))

a = QApplication(sys.argv)
w = MainWindow()
r = RunScript(w)
w.setWindowTitle('PyHybrid')
w.resize(1000,800)
w.show()
a.connect(w, SIGNAL('runPythonCode(QString)'), r.runScript)
a.connect(a, SIGNAL('lastWindowClosed()'), a, SLOT('quit()') )
a.exec_()
</pre>
<p>If you run it you will get same window as in c++ application except that python code entered in left panel with editor can be executed just here and the python code has control of our c++ part.</p>
<p>Let&#8217;s try small code snippets like:</p>
<pre  class="brush:python">
mainWindow.statusBar().show()
</pre>
<p>Oh! status bar is appeared in our application. Well, more complex maybe &#8211; let&#8217;s change background of canvas:</p>
<pre  class="brush:python">
mainWindow.scene.setBackgroundBrush(QColor('#e0e0ff'))
</pre>
<p>Can we create new objects? Of course yes:</p>
<pre  class="brush:python">
li1 = QGraphicsLineItem(10,10, 500,500)
li1.setPen(QPen(QBrush(QColor("#ff0000")), 3.0, Qt.DashLine))
mainWindow.scene.addItem(li1)
</pre>
<p><img src="http://lynxline.com/wp-content/uploads/2010/07/PyQtHybrid-2.png" alt="Example with a line" /></p>
<p>Can we create <em>new classes</em> just in <strong>real time</strong> and instanciate them???<br />
Sure yes!!!. Let&#8217;s create subclass of QGraphicsItem and make custom painting:</p>
<pre class="brush:python">
mainWindow.viewer.setRenderHint(QPainter.Antialiasing)
class MyItem(QGraphicsItem):
	def boundingRect(self):
		return QRectF(-100,-100,200,200)

	def paint(self, painter, option, widget):
		g = QLinearGradient(-100,-100, 100,100)
		g.setColorAt(0, QColor('#00ff00'))
		g.setColorAt(1, QColor('#ffffff'))
		painter.setBrush(g)
		p = QPen(QBrush(QColor("#ff0000")), 4, Qt.DashLine)
		painter.setPen(p)
		painter.drawRoundedRect(-100,-100,200,200, 30,30)

my1 = MyItem()
mainWindow.scene.addItem(my1)
my1.setPos(200,200)
</pre>
<p><img src="http://lynxline.com/wp-content/uploads/2010/07/PyQtHybrid-3.png" alt="Example with custom class" /></p>
<p>Well, so we can do everything with our small application &#8211; we can program it in real time. We can even generate code by program itself to execute it and more. Anyway, this also can be used for performance balancing when you can quickly prototype your code in python, and then transfer such code into C++ to make it running fast. </p>
<p>Good example &#8211; developing canvas-based games, when it can be really helpful and convenient to work with python code to make the logic, drawing etc and then migrate some code into C++.</p>
<p>Also it is very good for mobile devices &#8211; you program with python-pyside until you encounter performance issues and in this point you can easily separate critical part into c++ and keep Qt-like interface between these two parts.</p>
<p>Regarding our small application above &#8211; you can ask <em>What is the difference to just programming with your editor?</em> &#8211; <em><strong>You are coding your application while it is running.</strong></em> This is very new approach to programming with Qt. There is one especiality &#8211; you can loose your programming when exit <img src='http://lynxline.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> , So, it makes sense to modify the application to save all your code snippets to files.</p>
<p>It&#8217;s up to you.</p>
<p>I would like to thanks to PySide team. They are doing really great work and potential of PySide looks very exciting to be used in many projects.</p>
]]></content:encoded>
			<wfw:commentRss>http://lynxline.com/superhybrids-part-2-now-qt-pyside/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Jongling Qt models</title>
		<link>http://lynxline.com/jongling-qt-models/</link>
		<comments>http://lynxline.com/jongling-qt-models/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 09:47:22 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Models]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[Research]]></category>

		<guid isPermaLink="false">http://lynxline.com/?p=190</guid>
		<description><![CDATA[When you work intensively with data in your application then soon or not but you will realize that the best way of keeping them is some model object inherits from QAbstractItemModel, then data are hidden inside implementation of model. Adding, removing and modification are accessible through your API of the model class and it calls [...]]]></description>
			<content:encoded><![CDATA[<p>When you work intensively with data in your application then soon or not but you will realize that the best way of keeping them is some model object inherits from QAbstractItemModel, then data are hidden inside implementation of model. Adding, removing and modification are accessible through your API of the model class and it calls for appropriate model modifications (like beginInsertRows/endInsertRows). If you implement it in the way, then it is ideal for developer to use it in vews, operate with datas, implementing undo (see previous post: <a href="http://lynxline.com/undo-in-complex-qt-projects/">Undo in complex Qt projects</a>). </p>
<p>It is often situation when all application data are some kind of hierarchical tree of objects and properties. So, all of them can be kept in just one tree-like model class, but I see that developers do not use the approach and it happens because they do not see how some selective piece of data can be shown or have expectations of implementing own view classes, which is not trivial though and you may spent too much efforts there. Instead a lot of code related to synchronization between models can appear and it leads to complication of logic.</p>
<p>Same time, it can be resolved by implementation proxy models and use just standard view classes from Qt which are very effective. And I would like to show here that it is really simple:<br />
<span id="more-190"></span></p>
<p>There is simple example that I had to implement recently. The application shows list of objects, and same time it should show list of all properties of all objects. My first impression was to implement two separate models that may have shared data or base data are kept in one of model + some synchronization. But I saw that data manipulations leads to code complication + undo should be implemented smoothly. </p>
<p>We can implement just one model which is tree of objects (two levels). In one view (we can use QListView to show only first level of tree) we show listed objects. But what about another view to list of all objects of second level &#8211; we can implement proxy model which will be model of view</p>
<p><img src="http://lynxline.com/wp-content/uploads/2010/08/ModelMorph.png" alt="ProxyModel" /></p>
<p>Let&#8217;s have a look at QAbstractProxyModel. For mapping we need the implementation of mapFromSource() and mapToSource() plus rowCount / columnCount() / parent() and index().<br />
Because destination model is table-like, parent() returns just QModelIndex(), columnCount() returns count of source model, and index() returns just createIndex(row, column).<br />
More complex are rowCount(), mapFromSource() and mapToSource() because they need to calculate. (see a listings below)</p>
<p>Another piece of logic &#8211; appropriate behavior on adding /removing rows and data changes. QAbstractItemModel has very convenient signals reporting process of adding rows or columns. With recalculating indexes we can just call same methods of proxy models, like:</p>
<pre  class="brush:cpp">

...
connect(source, SIGNAL(rowsAboutToBeInserted(QModelIndex, int, int)),
        this, SLOT(s_rowsAboutToBeInserted(QModelIndex, int, int)));
connect(source, SIGNAL(rowsInserted(QModelIndex, int, int)),
        this, SLOT(s_rowsInserted(QModelIndex, int, int)));
...

void Proxy::s_rowsAboutToBeInserted(QModelIndex p, int from, int to)
{
    if (!p.isValid())
        return;

    int f = ... // calculate
    int t = ... // calculate
    beginInsertRows(QModelIndex(), f, t);
}

void Proxy::s_rowsInserted(QModelIndex p, int, int)
{
    // post adding routines if needed
    endInsertRows();
}
</pre>
<p>So, to summarize: it is not much efforts to implement proxy model which do appropriate data mappings in both directions. As benefit you have data kept in one place, all necessary signals by model to report changes in data (model). By mapping / proxying / filtering you can visualize in view any piece of data, even from different levels of hierarchy, etc. To visualize you can use just standard Qt view which are very effective.</p>
<p>Full listings of my proxy model:</p>
<p><a href="http://lynxline.com/wp-content/uploads/2010/08/UngroupProxyModel.h">UngroupProxyModel.h</a><br />
<a href="http://lynxline.com/wp-content/uploads/2010/08/UngroupProxyModel.cpp">UngroupProxyModel.cpp</a></p>
<p>Update:<br />
Read also <a href="http://lynxline.com/jongling-qt-models-2-composition-gem/" title="Jongling Qt models 2, Composition Gem">Jongling Qt models 2, Composition Gem</a></p>
]]></content:encoded>
			<wfw:commentRss>http://lynxline.com/jongling-qt-models/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Undo in complex Qt projects</title>
		<link>http://lynxline.com/undo-in-complex-qt-projects/</link>
		<comments>http://lynxline.com/undo-in-complex-qt-projects/#comments</comments>
		<pubDate>Wed, 28 Jul 2010 09:02:20 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[Undo]]></category>

		<guid isPermaLink="false">http://lynxline.com/?p=163</guid>
		<description><![CDATA[When you implement user interfaces, you should always be ready that your customers will ask very simple question: &#8220;Hey, where is undo in my application?&#8221;. Sometimes it makes developers totally puzzled because they haven&#8217;t even considered it. Then developers can find that they have to apply to project so much code changes and in so [...]]]></description>
			<content:encoded><![CDATA[<p>When you implement user interfaces, you should always be ready that your customers will ask very simple question: &#8220;Hey, where is undo in my application?&#8221;. Sometimes it makes developers totally puzzled <img src='http://lynxline.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  because they haven&#8217;t even considered it. Then developers can find that they have to apply to project so much code changes and in so much places, that definitely will reflect stability of project, bring new bugs etc.</p>
<p>So, what can be done there? Well, good to have it planned from beginning, but usually it does not happen, especially if several people worked on the project, some of them left project, some of them working only on command-line interface, etc.</p>
<p>It is possible that you need to implement undo in project which grown up to 100K lines of code and of course the primary question is how to do it smooth and transparent without affecting much code. I had similar experience and would like to share some tricks about it.</p>
<p><span id="more-163"></span></p>
<p>Let&#8217;s consider some project which compound of multiple components and one of them is model which used by several views and even used through filter/sorting proxy models. Usually developers quickly goes to cover everything than users can do in views, so they subclass views and start working hard on covering all actions there. Well, even if such idea works, this is not good, considering complexity of your project, and especially if there are multiple components and they are using each other, so they should now about undo actions of every other component in project. Are you using different views of same models? &#8211; well, you have to implement same undo few times in different view, oh wait, there is also filter/sorting model in middle &#8211; you have to code more, etc</p>
<p>You can get feeling that with implementing undo you started some avalanche in code of new dependencies, new apis, new methods, hundred of undo commands etc&#8230; Even more &#8211; you have to teach other developers how to apply undo or document it all very well.</p>
<p>Let&#8217;s try another approach &#8211; we can try to cover one single component without affecting API, and make it totally transparent for other classes in project.</p>
<p>Imaging that we have some model:</p>
<pre  class="brush:cpp">
class Model : public QAbstractItemModel { Q_OBJECT
public:
    Model(QObject * parent);
    virtual ~Model()

    // model reimpl:
    int rowCount(const QModelIndex &#038;parent = QModelIndex()) const;
    int columnCount(const QModelIndex &#038;parent = QModelIndex()) const;
    QVariant data(const QModelIndex &#038;index,
                  int role = Qt::DisplayRole) const;
    virtual bool setData(const QModelIndex&#038; index,
                         const QVariant &#038; value,
                         int role = Qt::EditRole);

    // you api
    virtual void add(Item *);
    virtual void remove(Item *);
};
</pre>
<p>There are 3 points where your model can be changed: add(), remove() and setData(). It is ideal to apply undo only in these 3 points and make it automatic. What means by &#8220;automatic&#8221;? &#8211; our code should know when apply undo and when not.</p>
<p>Remember that our project may also be used in command line mode. It makes sense not to mix model logic code with undo code, but we are not going to implement it in view, so let&#8217;s subclass our model and implement all Gui stuff and Undo there:</p>
<pre  class="brush:cpp">
class ModelGui : public Model { Q_OBJECT
public:
    ModelGui(QObject * parent);
    virtual ~ModelGui()

    QUndoStack * undoStack() const;
    void setUndoStack(QUndoStack *);

    // reimplemented for undo:
    virtual bool setData(const QModelIndex&#038; index,
                         const QVariant &#038; value,
                         int role = Qt::EditRole);

    virtual void add(Item *);
    virtual void remove(Item *);

private:
    class AddCmd;
    class RemoveCmd;
    class ChangeCmd;
};
</pre>
<p>We subclassed Model to reimplement add(), remove(), setData(), also we declared undo commands in &#8220;private&#8221; section (but we will define them in cpp to make them hidden). Now we need to implement add() where we cover it by undo command. Same time undo AddCmd should access &#8220;logic&#8221; add() method of superclass &#8211; we don&#8217;t need a recursion, so some kind of flag is needed, also it makes sense to make the flag kind of &#8220;global&#8221; to have control of covering actions by undo and in case of macro commands etc. Good trick to use &#8220;property&#8221; of qobject, also good to use as the qobject &#8211; the undo stack itself.</p>
<p>Let&#8217;s show implementation to make it clear:</p>
<pre  class="brush:cpp">
...

class ModelGui::AddCmd : public QUndoCommand {
public:
    AddCmd(ModelGui * m, Item * newItem): model(m), item(newItem) {}

    void redo() {
        bool cover = model->undoStack()->property('cover').toBool();
        model->undoStack()->setProperty('cover', false);
        model->Model::add(item);
        model->undoStack()->setProperty('cover', cover);
    }

    void undo() {
        bool cover = model->undoStack()->property('cover').toBool();
        model->undoStack()->setProperty('cover', false);
        model->Model::remove(item);
        model->undoStack()->setProperty('cover', cover);
    }

private:
    ModelGui * model;
    Item * item;
};

void ModelGui::add(Item * newItem) {
    bool cover = undoStack()->property('cover').toBool();
    if (cover) {
        undoStack()->beginMacro("Add Item");
        undoStack()->push(new AddCmd(this, newItem));
        undoStack()->endMacro();
    }
    else Model::add(newItem);
}

...
</pre>
<p>What we have accomplished here?</p>
<ul>
<li>There is single place where undo applied</li>
<li>Implementation of undo commands are hidden</li>
<li>Other classes or components don&#8217;t even need to know about undo in the model</li>
<li>You can use multiple views and sorting/filtering proxy models without worry about undo</li>
<li>If there is also command-line use of project, you just exclude ModelGui.h/cpp</li>
<li>If other component/module cast for add(), it is covered by undo automatically</li>
<li>If other undo command cast for add() from inside, it is not covered by undo &#8211; no recursion</li>
<li>The project can be as complex as possible, you only need to worry about using &#8220;cover&#8221;</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://lynxline.com/undo-in-complex-qt-projects/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Qt Python SuperHybrids</title>
		<link>http://lynxline.com/qt-python-superhybrids/</link>
		<comments>http://lynxline.com/qt-python-superhybrids/#comments</comments>
		<pubDate>Mon, 19 Jul 2010 13:08:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Embedding]]></category>
		<category><![CDATA[Hybrids]]></category>
		<category><![CDATA[PyQt]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[Research]]></category>

		<guid isPermaLink="false">http://lynxline.com/?p=90</guid>
		<description><![CDATA[You may know about PyQt &#8211; python bindings to Qt frameworks. They are great and allow to prototype gui Qt based code in very fast way. To my mind you can develop faster in 1.5-2 times comparing to same development cycle with Qt. Well, development is little different &#8211; you do not have compilation stage, [...]]]></description>
			<content:encoded><![CDATA[<p>You may know about PyQt &#8211; python bindings to Qt frameworks. They are great and allow to prototype gui Qt based code in very fast way. To my mind you can develop faster in 1.5-2 times comparing to same development cycle with Qt. Well, development is little different &#8211; you do not have compilation stage, but need to be more cautions about testing to be sure that all branches of executed code are tested, because you never know until they are executed at least once.</p>
<p>Currently you can find PyQt even for Maemo &#8211; <a href="http://forums.internettablettalk.com/showthread.php?s=3d53f32b5fe63a5fbd4b64211a4d4676&#038;t=42754">link</a></p>
<p><img src="http://lynxline.com/wp-content/uploads/2010/07/PyQt-Maemo.jpg" alt="PyQt-Maemo" /></p>
<p>Anyway, PyQt is great, python programming is fast, but one of frequently asked questions is &#8211; <br/><em>How can I integrate python scripting in my application and operate Qt Api from my scripts?, and why not?</em></p>
<p><span id="more-90"></span></p>
<p>When you can think that it is not possible, I would like to show the way how to do this and let&#8217;s even make working example.</p>
<p>Let&#8217;s start from scratch, assuming that you have installed and ready Qt Frameworks. (4.6.3 is used). First download such packages from PyQt homepage:</p>
<ul>
<li><a href="http://www.riverbankcomputing.co.uk/static/Downloads/sip4/sip-4.10.3.tar.gz">SIP</a></li>
<li><a href="http://www.riverbankcomputing.co.uk/static/Downloads/PyQt4/PyQt-mac-gpl-4.7.4.tar.gz">PyQt4</a> <em>(I used Mac platform for the example)</em></li>
</ul>
<p>Build sip:</p>
<pre  class="brush:shell">
# tar -zxf sip-4.10.3.tar.gz
# cd sip-4.10.3
# python configure.py
# make
# sudo make install
</pre>
<p>Build PyQt:</p>
<pre  class="brush:shell">
# tar -zxf PyQt-mac-gpl-4.7.4.tar.gz
# cd PyQt-mac-gpl-4.7.4
# python configure.py
# make
# sudo make install
</pre>
<p><em>(BTW: you may need to set the environment variable if configure does not work)</em></p>
<pre  class="brush:shell">
# export QMAKESPEC=macx-g++
</pre>
<p>Now, it is time to design small Qt application which we will use as base for executing PyQt routines.<br />
Let&#8217;s choose Canvas-based application &#8211; in such application we can prototype canvas items with PyQt<br />
during runtime of the application. Make it simple: two areas: plain text editor for python codes on left and canvas on right. </p>
<p>PyQtHybrid.pro:</p>
<pre  class="brush:perl">
TEMPLATE = app
CONFIG += qt
QT += core gui
HEADERS += MainWindow.h
SOURCES += MainWindow.cpp Main.cpp
</pre>
<p>Main.cpp:</p>
<pre  class="brush:cpp">
#include &lt;QtGui>
#include "MainWindow.h"
int main(int argc, char ** argv) {
    QApplication app(argc, argv);
    MainWindow window;
    window.resize(1000,700);
    window.show();
    return app.exec();
}
</pre>
<p>MainWindow.h:</p>
<pre  class="brush:cpp">
#ifndef MainWindow_H
#define MainWindow_H

#include &lt;QMainWindow>
class QPushButton;
class QGraphicsView;
class QGraphicsScene;
class QPlainTextEdit;

class MainWindow : public QMainWindow { Q_OBJECT
public:
    MainWindow(QWidget * parent = 0L);
    virtual ~MainWindow();

signals:
    void runPythonCode(QString);

private slots:
    void runPythonCode();

public:
    QGraphicsView * viewer;
    QGraphicsScene * scene;
    QPlainTextEdit * editor;
    QPushButton * pb_commit;
};
#endif // MainWindow_H
</pre>
<p>MainWindow.cpp:</p>
<pre  class="brush:cpp">
#include &lt;QtGui>
#include "MainWindow.h"

MainWindow::MainWindow(QWidget * parent):QMainWindow(parent) {
    QSplitter * splitter = new QSplitter;
    setCentralWidget(splitter);

    QWidget * editorContent = new QWidget;
    splitter->addWidget(editorContent);

    QVBoxLayout * layout = new QVBoxLayout;
    editorContent->setLayout(layout);

    editor = new QPlainTextEdit;
    layout->addWidget(editor);

    pb_commit = new QPushButton(tr("Commit"));
    connect(pb_commit, SIGNAL(clicked()),
            this, SLOT(runPythonCode()));
    layout->addWidget(pb_commit);

    scene = new QGraphicsScene(this);
    viewer = new QGraphicsView;
    viewer->setScene(scene);
    splitter->addWidget(viewer);

    splitter->setSizes(QList&lt;int>() << 400 << 600);
}

MainWindow::~MainWindow() {;}

void MainWindow::runPythonCode() {
    emit runPythonCode(editor->toPlainText());
}
</pre>
<p>As result we have a window with editor (left) and canvas (right):<br />
<img src="http://lynxline.com/wp-content/uploads/2010/07/PyQtHybrid-1.png" alt="MainWindow" /></p>
<p>Now it is time to modify application to get it working with PyQt. We are going to:</p>
<ul>
<li>Change application to dynamic library</li>
<li>Create wrappings for MainWindow class</li>
<li>Make Main.py instead of C main() routine</li>
</ul>
<p>For first point we just change TEMPLATE to lib, exclude Main.cpp, and build the shared lib.<br />
PyQtHybrid.pro:</p>
<pre  class="brush:perl">
TEMPLATE = lib
CONFIG += qt
QT += core gui
HEADERS += MainWindow.h
SOURCES += MainWindow.cpp
</pre>
<p>Now create folder &#8220;sip&#8221;. Inside we create a wrappings for our MainWindow class:<br />
MainWindow.sip:</p>
<pre  class="brush:cpp">
%Module PyQtHybrid 0
%Import QtGui/QtGuimod.sip
%If (Qt_4_2_0 -)

class MainWindow : QMainWindow {
%TypeHeaderCode
#include "../MainWindow.h"
%End
public:
    MainWindow();
    virtual ~MainWindow();

signals:
    void runPythonCode(QString);

private slots:
    void runPythonCode();

public:
    QGraphicsView * viewer;
    QGraphicsScene * scene;
    QPlainTextEdit * editor;
    QPushButton * pb_commit;
};

%End
</pre>
<p>To generate wrappings from sip we need a configure.py and PyQtHybridConfig.py.in.<br />
configure.py:</p>
<pre  class="brush:python">
import os
import sipconfig
from PyQt4 import pyqtconfig

build_file = "PyQtHybrid.sbf"
config = pyqtconfig.Configuration()
pyqt_sip_flags = config.pyqt_sip_flags

os.system(" ".join([ \
    config.sip_bin, \
    "-c", ".", \
    "-b", build_file, \
    "-I", config.pyqt_sip_dir, \
    pyqt_sip_flags, \
    "MainWindow.sip" \
]))

installs = []
installs.append(["MainWindow.sip", os.path.join(config.default_sip_dir, "PyQtHybrid")])
installs.append(["PyQtHybridConfig.py", config.default_mod_dir])

makefile = pyqtconfig.QtGuiModuleMakefile(
    configuration=config,
    build_file=build_file,
    installs=installs
)

makefile.extra_libs = ["PyQtHybrid"]
makefile.extra_lib_dirs = [".."]

makefile.generate()

content = {
    "PyQtHybrid_sip_dir":    config.default_sip_dir,
    "PyQtHybrid_sip_flags":  pyqt_sip_flags
}
sipconfig.create_config_module("PyQtHybridConfig.py", "PyQtHybridConfig.py.in", content)
</pre>
<p>PyQtHybridConfig.py.in</p>
<pre  class="brush:python">
from PyQt4 import pyqtconfig
# @SIP_CONFIGURATION@

class Configuration(pyqtconfig.Configuration):
    def __init__(self, sub_cfg=None):
        if sub_cfg: cfg = sub_cfg
        else: cfg = []
        cfg.append(_pkg_config)
        pyqtconfig.Configuration.__init__(self, cfg)

class PyQtHybridModuleMakefile(pyqtconfig.QtGuiModuleMakefile):
    def finalise(self):
        self.extra_libs.append("PyQtHybrid")
        pyqtconfig.QtGuiModuleMakefile.finalise(self)
</pre>
<p>Time to build Python module in &#8220;sip&#8221; folder (we assume that C++ lib is already built in top folder)</p>
<pre  class="brush:shell">
# python configure.py
# make
</pre>
<p>Almost everything is ready, time to connect everything in Main.py script:</p>
<pre  class="brush:python">
import sys
sys.path.append('sip')

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQtHybrid import *

class RunScript(QObject):
    def __init__(self, mainWindow):
        QObject.__init__(self)
        self.mainWindow = mainWindow

    def runScript(self, script):
        mainWindow = self.mainWindow
        exec(str(script))

a = QApplication(sys.argv)
w = MainWindow()
r = RunScript(w)
w.setWindowTitle('PyQtHybrid')
w.resize(1000,800)
w.show()
a.connect(w, SIGNAL('runPythonCode(QString)'), r.runScript)
a.connect(a, SIGNAL('lastWindowClosed()'), a, SLOT('quit()') )
a.exec_()
</pre>
<p>Now, if you run the Main.py you will get same window as we saw before, but, python code entered in left editor panel can be committed for execution by &#8230; well application itself&#8230;</p>
<p>We have an application which can program itself <img src='http://lynxline.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />  &#8211; that&#8217;s cool.</p>
<p>Let&#8217;s try small code snippets like:</p>
<pre  class="brush:python">
mainWindow.statusBar().show()
</pre>
<p>Oh! status bar is appeared in our application. Well, more complex maybe &#8211; let&#8217;s change background of canvas:</p>
<pre  class="brush:python">
mainWindow.scene.setBackgroundBrush(QColor('#e0e0ff'))
</pre>
<p>Can we create new objects? Of course yes:</p>
<pre  class="brush:python">
li1 = QGraphicsLineItem(10,10, 500,500)
li1.setPen(QPen(QBrush(QColor("#ff0000")), 3.0, Qt.DashLine))
mainWindow.scene.addItem(li1)
</pre>
<p><img src="http://lynxline.com/wp-content/uploads/2010/07/PyQtHybrid-2.png" alt="Example with a line" /></p>
<p>Can we create <em>new classes</em> just in <strong>real time</strong> and instanciate them???<br />
Sure yes!!!. Let&#8217;s create subclass of QGraphicsItem and make custom painting:</p>
<pre class="brush:python">
mainWindow.scene.clear()
mainWindow.viewer.setRenderHint(QPainter.Antialiasing)
class MyItem(QGraphicsItem):
	def boundingRect(self):
		return QRectF(-100,-100,200,200)

	def paint(self, painter, option, widget):
		g = QLinearGradient(-100,-100, 100,100)
		g.setColorAt(0, QColor('#00ff00'))
		g.setColorAt(1, QColor('#ffffff'))
		painter.setBrush(g)
		p = QPen(QBrush(QColor("#ff0000")), 4, Qt.DashLine)
		painter.setPen(p)
		painter.drawRoundedRect(-100,-100,200,200, 30,30)

my1 = MyItem()
mainWindow.scene.addItem(my1)
my1.setPos(200,200)
</pre>
<p><img src="http://lynxline.com/wp-content/uploads/2010/07/PyQtHybrid-3.png" alt="Example with custom class" /></p>
<p>Well, so we can do everything with our small application &#8211; we can program it in real time. We can even generate code by program itself to execute it and more. Anyway, this also can be used for performance balancing when you can quickly prototype your code in python, and then transfer such code into C++ to make it running fast. </p>
<p>Good example &#8211; developing canvas-based games, when it can be really helpful and convenient to work with python code to make the logic, drawing etc and then migrate some code into C++.</p>
<p>You can ask <strong>what is the difference to just programming with your editor?</strong> &#8211; <strong>You are coding your application while it is running.</strong> This is very new approach to programming with Qt. There is one especiality &#8211; you can loose your programming when exit <img src='http://lynxline.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> , So, it makes sense to modify the application to save all your code snippets to files.</p>
<p>It&#8217;s up to you.</p>
<p>Let&#8217;s hope to see LGPL PyQt packages sometimes&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://lynxline.com/qt-python-superhybrids/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Encode BuildId or Version into Application</title>
		<link>http://lynxline.com/encode-buildid-or-version-into-application/</link>
		<comments>http://lynxline.com/encode-buildid-or-version-into-application/#comments</comments>
		<pubDate>Wed, 09 Jun 2010 12:28:02 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Qt]]></category>

		<guid isPermaLink="false">http://lynxline.com/?p=86</guid>
		<description><![CDATA[There is very convenient way to encode identification of builds into applications. Then, for instance, you can show in about dialog something like: Version 20100609. Here is snippet of code: QString buildId() { QString embeddedDate(__DATE__); QString m = embeddedDate.left(3); QStringList months; months]]></description>
			<content:encoded><![CDATA[<p>There is very convenient way to encode identification of builds into applications. Then, for instance, you can show in about dialog something like: Version 20100609. Here is snippet of code:</p>
<p><span id="more-86"></span></p>
<pre  class="brush:cpp">
QString buildId()
{
    QString embeddedDate(__DATE__);
    QString m = embeddedDate.left(3);
    QStringList months;
    months << "Jan" << "Feb" << "Mar" << "Apr" << "May" << "Jun"
           << "Jul" << "Aug" << "Sep" << "Oct" << "Nov" << "Dec";

    int month = months.indexOf(m) + 1;
    int day   = embeddedDate.mid(4, 2).trimmed().toInt();
    int year  = embeddedDate.mid(7, 4).trimmed().toInt();

    return QString::number(year*10000+month*100+day);
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://lynxline.com/encode-buildid-or-version-into-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mac: mini font</title>
		<link>http://lynxline.com/mac-mini-font/</link>
		<comments>http://lynxline.com/mac-mini-font/#comments</comments>
		<pubDate>Wed, 14 Apr 2010 10:13:31 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Qt]]></category>

		<guid isPermaLink="false">http://lynxline.com/?p=78</guid>
		<description><![CDATA[On Mac you can often see the usage of two system fonts in applications. Second one &#8220;Mini&#8221; is convenient to use when you would like to have a lot of &#8220;mini&#8221; controls &#8211; mostly you can get it by applying Qt::WA_MacMiniSize. Well then the font is coming from mac style, but what if the font [...]]]></description>
			<content:encoded><![CDATA[<p>On Mac you can often see the usage of two system fonts in applications. Second one &#8220;Mini&#8221; is convenient to use when you would like to have a lot of &#8220;mini&#8221; controls &#8211; mostly you can get it by applying Qt::WA_MacMiniSize. Well then the font is coming from mac style, but what if the font is needed as QFont object?</p>
<p><span id="more-78"></span></p>
<pre  class="brush:cpp">
#ifdef Q_WS_MAC
    #include &lt;Carbon/Carbon.h&gt;
    //need a method from qglobal.cpp
    extern QString qt_mac_from_pascal_string(const Str255);
#endif

...

QFont systemMiniFont()
{
#ifdef Q_WS_MAC
    Str255 f_name;
    SInt16 f_size;
    Style f_style;
    static const ScriptCode Script = smRoman;

    GetThemeFont(kThemeSmallSystemFont, Script,
                 f_name, &#038;f_size, &#038;f_style);

    QFont font(qt_mac_from_pascal_string(f_name), f_size,
               (f_style &#038; ::bold) ? QFont::Bold : QFont::Normal,
               (bool)(f_style &#038; ::italic));

    return font;
#endif
    return qApp->font();
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://lynxline.com/mac-mini-font/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

