QT Computer Mad Science: Look Ma, No Code! (designer/creator experiment)
Posted 04-24-2012 at 08:22 AM by rainbowsally
Updated 04-24-2012 at 08:24 AM by rainbowsally (fixed a bum tag)
Updated 04-24-2012 at 08:24 AM by rainbowsally (fixed a bum tag)
I could have sworn that early versions of QT4 couldn't do this. It still can't do some things the old QT3 could do "progress" is like that, but it looks like this one might work if you have a somewhat recent version of QT4 (and designer or creator and kde).
Here's a bit of Computer Mad Science that you might find interesting. Or at least amusing.
Features:
file: src/digital_delay.ui
You can run run this in preview mode or compile it, especially if you have mc2 and the 'unofficial' mc2 -create qt4-files plugin setup, here:
http://www.linuxquestions.org/questi...eration-34648/
and of course, if you have kled.h which is (or should be) in the kdelibs development package.
We do actually learn something from this, believe it or not. The 'Yow' button doesn't react sometimes because other events are crowding it out when this is 'enabled' and running.
What this means is that QT just drops X events when it's too busy to read them, somehow. The button press events are getting as far as drawing the Yow button in its up and down positions but the message is not getting to the 'close()' method in QWidget that the button output is connected to.
Seems to work well enough most times BUT... there may be other times this behavior (or lack of it) can cause more serious problems. So we may want to see where in the system these button clicks are getting dropped.
Notes:
We discover that the function QT is using to wait for X events is
in the qeventdispatcher_glib.cpp, file around line 422.
And that g_main_context_iteration() function is defined in glib-2 in glib/gmain.c
The GMainContext struct is opaque, meaning that we cannot see what it consists of, and that's sure true enough. (But wait! See the screenshot at the bottom.) Does it contain a callback for QT or are the XEvents getting picked up by glib?
We DO want to know because QT should not be dropping events like this. (Tell yuh why later...)
Now there are a couple of places QT could be getting its XEvents. One possibility is the glib functions. We don't know because we never read the friggin' manuals -- for one, it's boring and for two, it describes only what they think "normal users" need to know.
Computer Mad Scientists are NOT "normal" users. So forget that.
The other place these X events could be coming from is from Xlib directly.
We could grep through the files and find out. But grepping glib is infinitely easier, which in the typical Gnome-ish style is a small file set, but doing a similar grep in QT is almost prohibitive.
Let's start by compiling QT's Gnome dependencies so we can let a debugger walk us through the code, which gives us 'animated documentation' in a practical application.
I'll try to toss in some fun stuff from time to time, but next up, let's see if our make-based system can create a debug version of glib that we can hook up with our debug version of QT4.
[Stay tuned for an example of a working example of using the make-based package installer to allow us to peek into the previously invisible parts of QT where it disappears into that glib function.]
And here's the QT surprise #2 from this very simple experiment: It's QT's dependecy on gnome libs for the QT main event loop.
Who'd a thunk it.
:-)
PS. re. opaque struct? Maybe for someone, but not for us.
http://rainbowsally.net/pub/lq/qt4-glib-dbg.jpg
The struct on the right had been "opaque". We can also see why glib is used, what it does, where it waits, and what it waits for. We can also see where it calls back to QT functions to handle various 'dispatch' types for various fids.
See the man page for "poll".
-- The Computer Mad Science Team
:-)
Here's a bit of Computer Mad Science that you might find interesting. Or at least amusing.
Features:
- It may run in preview mode without even compiling it.
- It may ONLY run in preview mode if you don't have kdelibs development files.
file: src/digital_delay.ui
Code:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>digital_delay</class>
<widget class="QWidget" name="digital_delay">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>362</width>
<height>166</height>
</rect>
</property>
<property name="windowTitle">
<string>MAd sCIeNcE - Digital Delay</string>
</property>
<widget class="QPushButton" name="btn_Clock">
<property name="geometry">
<rect>
<x>260</x>
<y>10</y>
<width>66</width>
<height>25</height>
</rect>
</property>
<property name="text">
<string>Clock</string>
</property>
</widget>
<widget class="QPushButton" name="Quit">
<property name="geometry">
<rect>
<x>260</x>
<y>120</y>
<width>75</width>
<height>26</height>
</rect>
</property>
<property name="text">
<string>Yow</string>
</property>
</widget>
<widget class="QFrame" name="frame">
<property name="geometry">
<rect>
<x>20</x>
<y>10</y>
<width>201</width>
<height>131</height>
</rect>
</property>
<property name="palette">
<palette>
<active>
<colorrole role="Button">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>96</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</active>
<inactive>
<colorrole role="Button">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>96</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>255</red>
<green>255</green>
<blue>255</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</inactive>
<disabled>
<colorrole role="Button">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>96</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Base">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
<colorrole role="Window">
<brush brushstyle="SolidPattern">
<color alpha="255">
<red>0</red>
<green>0</green>
<blue>0</blue>
</color>
</brush>
</colorrole>
</disabled>
</palette>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="KLed" name="led_2">
<property name="geometry">
<rect>
<x>70</x>
<y>70</y>
<width>25</width>
<height>25</height>
</rect>
</property>
<property name="state">
<enum>KLed::Off</enum>
</property>
</widget>
<widget class="KLed" name="led_3">
<property name="geometry">
<rect>
<x>30</x>
<y>70</y>
<width>25</width>
<height>25</height>
</rect>
</property>
<property name="state">
<enum>KLed::Off</enum>
</property>
</widget>
<widget class="QRadioButton" name="bit_2">
<property name="geometry">
<rect>
<x>73</x>
<y>23</y>
<width>25</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QRadioButton" name="bit_3">
<property name="geometry">
<rect>
<x>34</x>
<y>23</y>
<width>25</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="KLed" name="led_1">
<property name="geometry">
<rect>
<x>110</x>
<y>70</y>
<width>25</width>
<height>25</height>
</rect>
</property>
<property name="state">
<enum>KLed::Off</enum>
</property>
</widget>
<widget class="QRadioButton" name="bit_1">
<property name="geometry">
<rect>
<x>114</x>
<y>23</y>
<width>25</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QRadioButton" name="bit_0">
<property name="geometry">
<rect>
<x>153</x>
<y>23</y>
<width>25</width>
<height>21</height>
</rect>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="KLed" name="led_0">
<property name="geometry">
<rect>
<x>150</x>
<y>70</y>
<width>25</width>
<height>25</height>
</rect>
</property>
<property name="state">
<enum>KLed::Off</enum>
</property>
</widget>
</widget>
<widget class="QGroupBox" name="enable_2">
<property name="geometry">
<rect>
<x>250</x>
<y>40</y>
<width>91</width>
<height>61</height>
</rect>
</property>
<property name="font">
<font>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="title">
<string>enable</string>
</property>
<property name="flat">
<bool>true</bool>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<widget class="QRadioButton" name="run">
<property name="geometry">
<rect>
<x>30</x>
<y>30</y>
<width>50</width>
<height>19</height>
</rect>
</property>
<property name="text">
<string>run</string>
</property>
</widget>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<pixmapfunction>qPixmapFromMimeSource</pixmapfunction>
<customwidgets>
<customwidget>
<class>KLed</class>
<extends>QWidget</extends>
<header>kled.h</header>
</customwidget>
</customwidgets>
<includes>
<include location="local">kled.h</include>
<include location="local">kled.h</include>
<include location="local">kled.h</include>
<include location="local">kled.h</include>
</includes>
<resources/>
<connections>
<connection>
<sender>bit_0</sender>
<signal>released()</signal>
<receiver>bit_1</receiver>
<slot>animateClick()</slot>
</connection>
<connection>
<sender>bit_1</sender>
<signal>released()</signal>
<receiver>bit_2</receiver>
<slot>animateClick()</slot>
</connection>
<connection>
<sender>bit_2</sender>
<signal>released()</signal>
<receiver>bit_3</receiver>
<slot>animateClick()</slot>
</connection>
<connection>
<sender>btn_Clock</sender>
<signal>released()</signal>
<receiver>bit_0</receiver>
<slot>animateClick()</slot>
</connection>
<connection>
<sender>run</sender>
<signal>clicked()</signal>
<receiver>btn_Clock</receiver>
<slot>animateClick()</slot>
</connection>
<connection>
<sender>bit_3</sender>
<signal>released()</signal>
<receiver>run</receiver>
<slot>animateClick()</slot>
</connection>
<connection>
<sender>bit_0</sender>
<signal>toggled(bool)</signal>
<receiver>led_0</receiver>
<slot>toggle()</slot>
</connection>
<connection>
<sender>bit_1</sender>
<signal>toggled(bool)</signal>
<receiver>led_1</receiver>
<slot>toggle()</slot>
</connection>
<connection>
<sender>bit_2</sender>
<signal>toggled(bool)</signal>
<receiver>led_2</receiver>
<slot>toggle()</slot>
</connection>
<connection>
<sender>bit_3</sender>
<signal>toggled(bool)</signal>
<receiver>led_3</receiver>
<slot>toggle()</slot>
</connection>
<connection>
<sender>Quit</sender>
<signal>clicked()</signal>
<receiver>digital_delay</receiver>
<slot>close()</slot>
</connection>
<connection>
<sender>Quit</sender>
<signal>clicked()</signal>
<receiver>digital_delay</receiver>
<slot>close()</slot>
</connection>
</connections>
</ui>
http://www.linuxquestions.org/questi...eration-34648/
and of course, if you have kled.h which is (or should be) in the kdelibs development package.
Code:
mc2 -create qt4-files src/digital_delay.ui mc2 -fetch qt4 # edit mc2.def and change OUTNAME if you like and add -lkdeui # to the link like so: LDFLAGS = -lQtGui -lQtCore -lkdeui mc2 -u make clean; make
What this means is that QT just drops X events when it's too busy to read them, somehow. The button press events are getting as far as drawing the Yow button in its up and down positions but the message is not getting to the 'close()' method in QWidget that the button output is connected to.
Seems to work well enough most times BUT... there may be other times this behavior (or lack of it) can cause more serious problems. So we may want to see where in the system these button clicks are getting dropped.
Notes:
We discover that the function QT is using to wait for X events is
Code:
bool result = g_main_context_iteration(d->mainContext, canWait);
And that g_main_context_iteration() function is defined in glib-2 in glib/gmain.c
Code:
gboolean g_main_context_iteration (GMainContext *context, gboolean may_block)
{
gboolean retval;
if (!context)
context = g_main_context_default();
LOCK_CONTEXT (context);
retval = g_main_context_iterate (context, may_block, TRUE, G_THREAD_SELF);
UNLOCK_CONTEXT (context);
return retval;
}
We DO want to know because QT should not be dropping events like this. (Tell yuh why later...)
Now there are a couple of places QT could be getting its XEvents. One possibility is the glib functions. We don't know because we never read the friggin' manuals -- for one, it's boring and for two, it describes only what they think "normal users" need to know.
Computer Mad Scientists are NOT "normal" users. So forget that.
The other place these X events could be coming from is from Xlib directly.
We could grep through the files and find out. But grepping glib is infinitely easier, which in the typical Gnome-ish style is a small file set, but doing a similar grep in QT is almost prohibitive.
Let's start by compiling QT's Gnome dependencies so we can let a debugger walk us through the code, which gives us 'animated documentation' in a practical application.
I'll try to toss in some fun stuff from time to time, but next up, let's see if our make-based system can create a debug version of glib that we can hook up with our debug version of QT4.
[Stay tuned for an example of a working example of using the make-based package installer to allow us to peek into the previously invisible parts of QT where it disappears into that glib function.]
And here's the QT surprise #2 from this very simple experiment: It's QT's dependecy on gnome libs for the QT main event loop.
Code:
Report bugs to <http://bugzilla.gnome.org/enter_bug.cgi?product=glib>.
:-)
PS. re. opaque struct? Maybe for someone, but not for us.
http://rainbowsally.net/pub/lq/qt4-glib-dbg.jpg
The struct on the right had been "opaque". We can also see why glib is used, what it does, where it waits, and what it waits for. We can also see where it calls back to QT functions to handle various 'dispatch' types for various fids.
See the man page for "poll".
-- The Computer Mad Science Team
:-)
Total Comments 0




