LinuxQuestions.org
Go Job Hunting at the LQ Job Marketplace
Go Back   LinuxQuestions.org > Blogs > rainbowsally
User Name
Password

Notices



Rate this Entry

QT Computer Mad Science: Look Ma, No Code! (designer/creator experiment)

Posted 04-24-2012 at 09:22 AM by rainbowsally
Updated 08-06-2014 at 11:19 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:
  • 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.
Here's the ui file with all the <hints><...blah blah...></hints> stripped out in order to reduce the size a nub.

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>
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.

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
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
Code:
bool result = g_main_context_iteration(d->mainContext, canWait);
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

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;
}
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.
Code:
Report bugs to <http://bugzilla.gnome.org/enter_bug.cgi?product=glib>.
Who'd a thunk it.

:-)

PS. re. opaque struct? Maybe for someone, but not for us.

http://rainbowsally.org/rainbowsally...4-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

:-)
Posted in Uncategorized
Views 284 Comments 0
« Prev     Main     Next »
Total Comments 0

Comments

 

  



All times are GMT -5. The time now is 02:04 AM.

Main Menu
Advertisement

Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration