<?xml version="1.0" encoding="ISO-8859-15"?>
<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>etd's Dos and Dont's &#187; X Windows</title>
	<atom:link href="http://weblog.nomejortu.com/category/x-windows/feed" rel="self" type="application/rss+xml" />
	<link>http://weblog.nomejortu.com</link>
	<description>specialization is for insects</description>
	<lastBuildDate>Sun, 20 Jul 2008 21:45:15 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>ruby workshop: the way of the Qt samurai</title>
		<link>http://weblog.nomejortu.com/x-windows/ruby-workshop-the-way-of-the-qt-samurai</link>
		<comments>http://weblog.nomejortu.com/x-windows/ruby-workshop-the-way-of-the-qt-samurai#comments</comments>
		<pubDate>Mon, 17 Dec 2007 16:23:56 +0000</pubDate>
		<dc:creator>etd</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[X Windows]]></category>

		<guid isPermaLink="false">http://weblog.nomejortu.com/?p=31</guid>
		<description><![CDATA[As a side result of my work with dradis during the last months, I&#8217;ve been working on some technical sessions that will be grouped in what could be called a &#8220;ruby workshop&#8221;. The first of this sessions is on ruby + Qt programming and is available now.

Slides can be found here.
Source and examples: here.

]]></description>
			<content:encoded><![CDATA[<p>As a side result of my work with <a href="http://dradis.nomejortu.com/">dradis</a> during the last months, I&#8217;ve been working on some technical sessions that will be grouped in what could be called a &#8220;ruby workshop&#8221;. The first of this sessions is on ruby + Qt programming and is available now.</p>
<ul>
<li>Slides can be found <a href="/data/files/qtsamurai-slides.pdf">here</a>.</li>
<li>Source and examples: <a href="/data/files/qtsamurai-code.tar.bz2">here</a>.</li>
</ul>
<img src="http://weblog.nomejortu.com/?ak_action=api_record_view&id=31&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.nomejortu.com/x-windows/ruby-workshop-the-way-of-the-qt-samurai/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>using the fox toolkit in ruby</title>
		<link>http://weblog.nomejortu.com/x-windows/using-the-fox-toolkit-library</link>
		<comments>http://weblog.nomejortu.com/x-windows/using-the-fox-toolkit-library#comments</comments>
		<pubDate>Tue, 02 Oct 2007 13:15:43 +0000</pubDate>
		<dc:creator>etd</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[X Windows]]></category>

		<guid isPermaLink="false">http://weblog.nomejortu.com/?p=26</guid>
		<description><![CDATA[The fox toolkit is a portable C++ graphical library. If you download old code (such as the nice rubyforger &#8211; that sits on top of libnet and libpcap) you may end up with some headache, so these easy steps will help to get your fox application up and running 

Download and install the development files [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://www.fox-toolkit.org/">fox toolkit</a> is a portable C++ graphical library. If you download old code (such as the nice <a href="http://rubyforger.rubyforge.org/">rubyforger</a> &#8211; that sits on top of <a href="http://www.packetfactory.net/libnet/">libnet</a> and <a href="http://www.tcpdump.org/">libpcap</a>) you may end up with some headache, so these easy steps will help to get your fox application up and running <img src='http://weblog.nomejortu.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /><br />
<span id="more-26"></span><br />
Download and install the development files for the fox library:<br />
<code><br />
apt-get install libfox-1.6-dev<br />
</code></p>
<p>Download the fox gem. In order to compile it, you may need to download the <code>ruby1.8-dev</code> package:<br />
<code><br />
gem install fxruby<br />
</code></p>
<p>Once this is done, open the old file where you should find something like:<br />
<code><br />
require 'fox14'</p>
<p>include Fox</p>
<p>#----- more stuff<br />
</code></p>
<p>You need to modify that to make it look something like:<br />
<code><br />
require 'rubygems'<br />
gem 'fxruby'<br />
require 'fox16'</p>
<p>include Fox</p>
<p>#----- more stuff<br />
</code></p>
<p>And that should make it.</p>
<img src="http://weblog.nomejortu.com/?ak_action=api_record_view&id=26&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.nomejortu.com/x-windows/using-the-fox-toolkit-library/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ruby Qt: model / view / controller</title>
		<link>http://weblog.nomejortu.com/x-windows/ruby-qt-model-view-controller</link>
		<comments>http://weblog.nomejortu.com/x-windows/ruby-qt-model-view-controller#comments</comments>
		<pubDate>Wed, 15 Aug 2007 18:10:20 +0000</pubDate>
		<dc:creator>etd</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[X Windows]]></category>

		<guid isPermaLink="false">http://weblog.nomejortu.com/?p=21</guid>
		<description><![CDATA[From the wikipedia:

Model-view-controller (MVC) is an architectural pattern used in software engineering. In complex computer applications that present a large amount of data to the user, a developer often wishes to separate data (model) and user interface (view) concerns, so that changes to the user interface will not affect data handling, and that the data [...]]]></description>
			<content:encoded><![CDATA[<p>From the <a href="http://en.wikipedia.org/wiki/Model-view-controller">wikipedia</a>:</p>
<blockquote><p>
<strong>Model-view-controller</strong> (<strong>MVC</strong>) is an architectural pattern used in software engineering. In complex computer applications that present a large amount of data to the user, a developer often wishes to separate data (model) and user interface (view) concerns, so that changes to the user interface will not affect data handling, and that the data can be reorganized without changing the user interface.
</p></blockquote>
<p>MVC is not only useful for web frameworks and applications, here is a simple example of the implementation of the MVC pattern for a Qt <acronym title="Graphical User Interface">GUI</acronym> application.<br />
<span id="more-21"></span><br />
For this example the <em>business data</em> (Model) will consist of just a <strong>counter</strong>. The <acronym title="Graphical User Interface">GUI</acronym> (View) will have elements to increase and decrease this counter. Since this is a very small proof-of-concept application there is no need for a Controller component. You can have a look at the <a href="/data/code/ruby/mvc.rb">code</a> before we start.</p>
<p>First the Model class:-</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre>class Model &lt; Qt::Object
  slots 'increase()', 'decrease()'
  signals 'modified()'
  
  attr :counter
  
  def initialize 
    super
    @counter = 0
  end
  
  def increase
    @counter += 1
    emit modified()
  end
  
  def decrease
    @counter -= 1
    emit modified()
  end
end</pre></div></div>
<p>The Model extends <code>Qt::Object</code> so we can inherit the <strong>signals</strong> /<strong> slots</strong> functionality.  Signals and slots will be the mechanisms used by our components to talk to each other. The class defines two slots: <code>increase()</code> and <code>decrease()</code>. If an external component wants to modify the data kept by the Model, the component will send a <em>signal</em> to one of these slots. In the same way, one the value of the counter is modified, the Model will emit the <code>modified()</code> signal.</p>
<p>The View class contains only two methods: the constructor and one slot. In the constructor we create the widgets of the interface and then connect the different <strong>signals</strong> and <strong>slots</strong> (more on this later). A single <strong>slot</strong> is defined in the class: <code>counter_modified()</code>. This slot will receive the signal sent by the Model each time the underlaying data is modified. Here is the code:-</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre>class View &lt; Qt::Widget
  slots 'counter_modified()'
  
  def initialize(model)
    super(nil)
    
    # keep a reference to the model
    @model = model
    
    # define widgets and layout
    grid = Qt::GridLayout.new
    @btn1 = Qt::PushButton.new('+1')
    @btn2 = Qt::PushButton.new('-1')
    @lcd = Qt::LCDNumber.new
    grid.addWidget(@btn1)
    grid.addWidget(@btn2)
    grid.addWidget(@lcd)
    self.setLayout(grid)
    
    # connect signals and slots between the Model and the View
    connect @btn1, SIGNAL('clicked()'), @model, SLOT('increase()')
    connect @btn2, SIGNAL('clicked()'), @model, SLOT('decrease()')
    connect @model, SIGNAL('modified()'), self, SLOT('counter_modified()')
  end
  

  def counter_modified
    @lcd.display(@model.counter)
  end
end</pre></div></div>
<p>As mentioned earlier we are not using a Controller component for this example. However, the <em>controller</em> behaviour still exist but is included in the View class. </p>
<p>The Model has two slots and is able to emit a signal. We only need to bind this messages with the corresponding widgets in the user interface. The lines below connect the <code>clicked()</code> of the buttons with the different <strong>slots</strong> of the Model. Likewise, the <code>modified()</code> signal of the Model is connected to the <code>counter_modified()</code> slot of the View.</p>
<div class="hl-surround" ><div class="hl-main"><pre>connect @btn1, SIGNAL('clicked()'), @model, SLOT('increase()')
connect @btn2, SIGNAL('clicked()'), @model, SLOT('decrease()')
connect @model, SIGNAL('modified()'), self, SLOT('counter_modified()')</pre></div></div>
<p>When the Model emits the <code>modified()</code> signal, the View will update the value displayed in the <a href="http://doc.trolltech.com/4.0/qlcdnumber.html">Qt::LCDNumber</a> widget.</p>
<p>More complex data models may require more complex patterns, but that is another story and shall be told another time.</p>
<img src="http://weblog.nomejortu.com/?ak_action=api_record_view&id=21&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.nomejortu.com/x-windows/ruby-qt-model-view-controller/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ruby Qt: menu bar, status bar and resources</title>
		<link>http://weblog.nomejortu.com/x-windows/ruby-qt-menu-bar-status-bar-and-resources</link>
		<comments>http://weblog.nomejortu.com/x-windows/ruby-qt-menu-bar-status-bar-and-resources#comments</comments>
		<pubDate>Tue, 31 Jul 2007 15:31:35 +0000</pubDate>
		<dc:creator>etd</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[X Windows]]></category>

		<guid isPermaLink="false">http://weblog.nomejortu.com/?p=19</guid>
		<description><![CDATA[Menu and status bar are two elements that you expect to find in most applications out there. Menu bars are rich elements that consists of menu items and actions. Each action consists of a text and optionally a shortcut and an icon.

First things first, we are going to create a small application with just a [...]]]></description>
			<content:encoded><![CDATA[<p>Menu and status bar are two elements that you expect to find in most applications out there. Menu bars are rich elements that consists of menu items and actions. Each action consists of a text and optionally a shortcut and an icon.<br />
<span id="more-19"></span><br />
First things first, we are going to create a small application with just a menu bar and a status bar:</p>
<div class="hl-surround" ><div class="hl-main"><pre>#require Qt4 bindings for ruby
require 'Qt4'

class MenuWindow &lt; Qt::MainWindow
end

if $0 == __FILE__
    a = Qt::Application.new(ARGV)
    w = MenuWindow.new
    w.show
    a.exec
end</pre></div></div>
<p>Now that we have our main window we can start adding widgets. We begin with the menu bar and two top level menu items. We will override the default constructor of MenuWindow:</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre>def initialize
    super

    # create the menu bar
    @menubar = Qt::MenuBar.new(self)
    @menubar.setObjectName('menubar')
    
    # create the top level menu items
    @menuFile = Qt::Menu.new(@menubar)
    @menuFile.setObjectName('menuFile')
    @menuFile.setTitle('File')
    @menuHelp = Qt::Menu.new(@menubar)
    @menuHelp.setObjectName('menuHelp')
    @menuHelp.setTitle('&amp;Help')

    # add the top level menu items to the menu bar
    @menubar.addAction(@menuFile.menuAction())
    @menubar.addAction(@menuHelp.menuAction())

    # attach the bar to the window
    self.setMenuBar(@menubar)
  end</pre></div></div>
<p>The only difference between these two elements is the ampersand (<code>&#038;</code>)  symbol in their title. For those new to GUI development and ampersand in the title of a menu will be painted as an underscore of the letter that follows. When the user presses the special combination <em>Alt+H</em> the <strong>Help</strong> menu will be highlighted. No special combination is associated to the <strong>File</strong> menu.</p>
<p>The next step is to add some actions for out menus. We are trying to have the following structure:</p>
<ul>
<li>File
<ul>
<li>Open</li>
<li>(separator)</li>
<li>Exit</li>
</ul>
</li>
<li>Help
<ul>
<li>About</li>
</ul>
</li>
</ul>
<p>Which can be accomplished by adding the following code to the constructor above:</p>
<div class="hl-surround" ><div class="hl-main"><pre># create menu actions
@actionOpen = Qt::Action.new(self)
@actionOpen.setObjectName('actionOpen')
@actionOpen.setText('Open')

@actionExit = Qt::Action.new(self)
@actionExit.setObjectName('actionExit')
@actionExit.setText('Exit')

@actionAbout = Qt::Action.new(self)
@actionAbout.setObjectName('actionAbout')
@actionAbout.setText('About')

# attach actions to top level menu items
@menuFile.addAction(@actionOpen)
@menuFile.addSeparator()
@menuFile.addAction(@actionExit)

@menuHelp.addAction(@actionAbout)</pre></div></div>
<p>The results of the code can be seen in the following capture:-</p>
<p><img src="/data/img/snap_plainmenu.png" alt="Main window with menu bar, items and actions" /></p>
<p>There are three different properties that you may be interested in changing on a given menu action: </p>
<ul>
<li>The <em>shortcut</em> is a special combination of keys that when pressed effectively send the <code>activated()</code> signal of an action. </li>
<li>The <em>status bar message</em> is the message that will be displayed in the status bar when the user hovers the pointer over the action. </li>
<li>The <em>icon</em> that will be displayed on the left of the action&#8217;s text.</li>
</ul>
<p>In order to show how the status bar message behaves we need to create and attach a status bar to our application. This can be done by adding the following code to the constructor of our main window:</p>
<div class="hl-surround" ><div class="hl-main"><pre># create and attach the status bar
@statusbar = Qt::StatusBar.new(self)
@statusbar.setObjectName('statusbar')
self.setStatusBar(@statusbar)</pre></div></div>
<p>So now we can add a short message that will be displayed in the status bar to our actions, for example: <code>@actionOpen.setStatusTip('Open a new file')</code>. </p>
<p>Almost as easy is to add a shortcut combination: <code>@actionExit.setShortcut('Ctrl+X')</code>.</p>
<p>A combination of the two at work can be seen in the following capture:-</p>
<p><img src="/data/img/snap_statusmenu.png" alt="Menu actions with shortcuts and status bar message" /></p>
<p>The most tricky of the three is the <em>icon</em> property. Resources (as images) in Qt can be loaded in three different ways:</p>
<ul>
<li>At <strong>run time</strong></li>
<li>By using a <strong>resource</strong> file</li>
<li>Or by loading one of the built-in resources</li>
</ul>
<p>The easiest way of adding an icon to an action is by loading the resource at run time: <code>@actionOpen.setIcon(Qt::Icon.new('icons/fileopen.png'))</code>. This will try to load the given image from the file system at runtime. </p>
<p>If you do not want to distribute icons as separate files you can group them in Qt resource file. A resource file  (usually with <strong>.qrc</strong> extension) is an XML file containing resource descriptions. You can see an example here:</p>
<div class="hl-surround" ><div class="hl-main"><pre>&lt;RCC&gt;
    &lt;qresource prefix=&quot;/&quot; &gt;
        &lt;file&gt;icons/help.png&lt;/file&gt;
    &lt;/qresource&gt;
&lt;/RCC&gt;</pre></div></div>
<p>This file needs to be compiled, we will cover that in a second, but provided that you have the file compiled, to use a resource of the file you just need something like this:</p>
<div class="hl-surround" ><div class="hl-main"><pre>#require the compiled resources file
require 'resources'
[...]
  # inside the constructor
  @actionAbout.setIcon(Qt::Icon.new(':/icons/help.png'))
[...]</pre></div></div>
<p>Notice the colon (<strong>:</strong>) before the path in the method call. A path is constructed by appending the prefix (<em>/</em>) to the file name of the resource (<em>icons/help.png</em>). Also note that before compiling the resources file you need a subdirectory called <em>icons</em> and a file named <em>help.png</em> inside it in order to produce the desired output.</p>
<p>In order to compile a .qrc file you will need the standard tool <code>rbrcc</code> whose syntax is as follows:</p>
<div class="hl-surround" style="height:28px;"><div class="hl-main"><pre>rbrcc resources.qrc -o resources.rb</pre></div></div>
<p>That command will try to find all the referenced resources in the <strong>.qrc</strong> file and compile and compress them into the <strong>.rb</strong> file.<br />
The third way to assign an icon to an action is by using one of the standard pixmaps built-in the Qt library. If you want to use one of these default resources, the code you need is the following: <code>@actionExit.setIcon(self.style().standardIcon(<strong>PixmapCode</strong>))</code> where <strong>PixmapCode</strong> is defined in the <a href="http://doc.trolltech.com/4.0/qstyle.html#StandardPixmap-enum">QStyle</a> class. Some of the values that can be used are listed below:</p>
<ul>
<li>QStyle::SP_DesktopIcon</li>
<li>QStyle::SP_TrashIcon</li>
<li>QStyle::SP_ComputerIcon</li>
<li>QStyle::SP_TitleBarCloseButton</li>
<li>QStyle::SP_FileIcon</li>
</ul>
<p>I have left a <a href="/data/files/qtmenuplay.tar">tar file</a> containing all the files required for this example. The three icon loading techniques shown above are used in the example. And remember that you will need to compile the <strong>.qrc</strong> file before running it.</p>
<img src="http://weblog.nomejortu.com/?ak_action=api_record_view&id=19&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.nomejortu.com/x-windows/ruby-qt-menu-bar-status-bar-and-resources/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>ruby Qt custom widget example</title>
		<link>http://weblog.nomejortu.com/x-windows/ruby-qt-custom-widget-example</link>
		<comments>http://weblog.nomejortu.com/x-windows/ruby-qt-custom-widget-example#comments</comments>
		<pubDate>Sun, 03 Jun 2007 23:08:16 +0000</pubDate>
		<dc:creator>etd</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[X Windows]]></category>

		<guid isPermaLink="false">http://weblog.nomejortu.com/?p=18</guid>
		<description><![CDATA[With Qt&#8217;s custom widgets you can create the building blocks of the GUI of your application.
In this case we are creating a graphical command line. The command line will consist mainly of a text input box (Qt::LineEdit). The widget will have memory, that is, every line entered by the user will be added to the [...]]]></description>
			<content:encoded><![CDATA[<p>With Qt&#8217;s custom widgets you can create the building blocks of the GUI of your application.</p>
<p>In this case we are creating a graphical <strong>command line</strong>. The <em>command line</em> will consist mainly of a text input box (<a href="http://doc.trolltech.com/4.0/qlineedit.html">Qt::LineEdit</a>). The widget will have <em>memory</em>, that is, every line entered by the user will be added to the internal <strong>history</strong> of the widget and will be accessible by means of Up and Down arrows as the standard <em>*nix</em> command line.</p>
<p><span id="more-18"></span></p>
<p>Here is the <a href="http://weblog.nomejortu.com/data/code/ruby/commandline.rb">code</a>:-</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre>=begin
**
** commandline.rb
** 03/JUN/2007
** ETD-Software
**  - Daniel Martin Gomez &lt;etd[-at-]nomejortu.com&gt;
**
** Desc:
**   Qt custom widget that behaves as a standard command line. It keeps a 
** buffer of commands that can be accessed by pressing Up and Down keys.
**
** Version:
**  v1.0 [03/Jun/2007]: first released
**
** This file may be used under the terms of the GNU General Public
** License version 2.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of
** this file.  Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
** http://www.trolltech.com/products/qt/opensource.html
**
=end

require 'Qt4'

class CommandLine &lt; Qt::LineEdit
  slots 'clear_history()'

  def initialize(parent=nil)
    super(parent)
    #initialize internal history buffer
    @history = []
    @pointer = 0
  end

  #override some event handlers
  def keyPressEvent(event)
    case event.key 
      when Qt::Key_Up:
        if ((@history.size &gt; 0) &amp;&amp; (@pointer &gt;= 0) )
          if (@pointer == @history.size)
            @history &lt;&lt; self.text 
          end
          @pointer -= 1 if @pointer &gt; 0
          self.text = @history[@pointer]
        end
        return

      when Qt::Key_Down:
        if ((@history.size &gt; 0) &amp;&amp; (@pointer &lt; @history.size) )
          @pointer += 1 if @pointer &lt; @history.size - 1
          self.text = @history[@pointer]
        end
        return

      #add a new element to the local @history
      when Qt::Key_Return:

        #keep an eye on the last entry to avoid empty entries in the list
        if ((@history.size &gt; 0) &amp;&amp; (@history.last.strip.size == 0) )
          @history.pop
        end

        if self.text.strip.size &gt; 0
          @history &lt;&lt; self.text
          @pointer = @history.size
          self.clear
        else
          return
        end
    end

    super
  end


  def clear_history()
    @history.clear
  end

  def last_command()
    @history.last
  end
end

if $0 == __FILE__
    a = Qt::Application.new(ARGV)
    w = CommandLine.new
    w.show
    a.exec
end</pre></div></div>
<p>As you can see, out widget inherits from standard Qt LineEdit widget:-<br />
<code>class CommandLine < Qt::LineEdit</code></p>
<p>When instancing a copy of the widget we set up two variables to handle the internal history:-</p>
<div class="hl-surround" ><div class="hl-main"><pre>def initialize(parent=nil)
  super(parent)
  #initialize internal history buffer
  @history = []
  @pointer = 0
end</pre></div></div>
<p><strong>@history</strong> array contains the list of commands typed by the user. <strong>@pointer</strong> is a pointer to the element of the list that will be displayed when Up or Down keys are pressed.</p>
<p>All the widget's functionality is coded in the <strong>keyPressEvent</strong> of the class. This method is called everytime the user introduces a new letter in the box. We are adding special functionality for three letters: <em>Qt::Key_Up</em>, <em>Qt::Key_Down</em> and <em>Qt::Key_Return</em>.</p>
<div class="hl-surround" ><div class="hl-main"><pre>when Qt::Key_Up:
  if ((@history.size &gt; 0) &amp;&amp; (@pointer &gt;= 0) )
    if (@pointer == @history.size)
      @history &lt;&lt; self.text 
    end
    @pointer -= 1 if @pointer &gt; 0
    self.text = @history[@pointer]
  end
  return</pre></div></div>
<p>If the <strong>@history</strong> contains elements and the <em>Qt::Key_Up</em> is pressed we move the pointer to the correct place in the <strong>@history</strong> list and then replace the current text of the box. However, if the user decides to press the Up arrow in the middle of a new line, we add this new line to the <strong>@history</strong> before continuing.</p>
<div class="hl-surround" ><div class="hl-main"><pre>when Qt::Key_Down:
  if ((@history.size &gt; 0) &amp;&amp; (@pointer &lt; @history.size) )
    @pointer += 1 if @pointer &lt; @history.size - 1
    self.text = @history[@pointer]
  end
  return</pre></div></div>
<p>Likewise, if the Down arrow is pressed we move the <strong>@pointer</strong> down the list and replace the text.</p>
<p>The last case when we intercept the <em>KeyPress</em> event is when the user hits the Return key. The first <strong>if</strong> gets rid of the last element of the <strong>@history</strong> if it is empty. Reme,ber when we added the current line to the history in the <em>Qt::Key_Up</em> case? This if removes that element if it was an empty line.</p>
<div class="hl-surround" ><div class="hl-main"><pre>when Qt::Key_Return:
  #keep an eye on the last entry to avoid empty entries in the list
  if ((@history.size &gt; 0) &amp;&amp; (@history.last.strip.size == 0) )
    @history.pop
  end

  if self.text.strip.size &gt; 0
    @history &lt;&lt; self.text
    @pointer = @history.size
    self.clear
  else
    return
  end</pre></div></div>
<p>We then check that the current line is not empty. We add the text to the widget's history and clear the box. If the line is empty we <strong>return</strong>, so no <em>keyPressed()</em> signal is raised.</p>
<p>The script contains helper code to test it by creating a Qt application and showing the widget.</code></p>
<img src="http://weblog.nomejortu.com/?ak_action=api_record_view&id=18&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.nomejortu.com/x-windows/ruby-qt-custom-widget-example/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ruby Qt::TreeWidget example</title>
		<link>http://weblog.nomejortu.com/x-windows/ruby-qttreewidget-example</link>
		<comments>http://weblog.nomejortu.com/x-windows/ruby-qttreewidget-example#comments</comments>
		<pubDate>Sat, 02 Jun 2007 16:23:43 +0000</pubDate>
		<dc:creator>etd</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[X Windows]]></category>

		<guid isPermaLink="false">http://weblog.nomejortu.com/?p=17</guid>
		<description><![CDATA[I am involved in some projects were we are using Qt library for GUI development with ruby. In the following example I will show how to use the Qt::TreeWidget object.
The TreeWidget can be used not only to display information hierarchically but also to add multiple columns to the data model.

We are going to use a [...]]]></description>
			<content:encoded><![CDATA[<p>I am involved in some projects were we are using <a href="http://doc.trolltech.com/4.0/index.html">Qt library</a> for GUI development with ruby. In the following example I will show how to use the <a href="http://doc.trolltech.com/4.0/qtreewidget.html">Qt::TreeWidget</a> object.</p>
<p>The TreeWidget can be used not only to display information hierarchically but also to add multiple columns to the data model.<br />
<span id="more-17"></span><br />
We are going to use a simple example in which we will populate our TreeWidget with filesystem information.</p>
<p>Below is a screen capture of what we want to accomplish:-<br />
<img src="http://weblog.nomejortu.com/data/img/snap_treedemo.png" alt="Qt::TreeWidget in action: hierarchy and columns combined" /></p>
<p>Here is the <a href="http://weblog.nomejortu.com/data/code/ruby/treedemo.rb">code</a>:-</p>
<div class="hl-surround" style="height:280px;"><div class="hl-main"><pre>=begin
**
** treedemo.rb
** 02/JUN/2007
** Daniel Martin Gomez
**
** Desc:
**  This script shows how to use the Qt::TreeWidget object. It populates a tree
**  using filesystem directory information. Please note that this should only
**  be used as an usage example of the widget. See Qt::DirModel for
**  implementing directory tree behaviour.
**
** Version:
**  v1.0 [02/Jun/2007]: first released
**
** This file may be used under the terms of the GNU General Public
** License version 2.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of
** this file.  Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
** http://www.trolltech.com/products/qt/opensource.html
**
=end

#require Qt4 bindings for ruby
require 'Qt4'

$DEFAULT_PATH = '/home/etd'


#populate the tree
def populate(tree, path, parent=nil)
  Dir[&quot;#{path}/*&quot;].each do |file|
    #fill item information
    item = Qt::TreeWidgetItem.new()
    item.setText(0, File.basename(file))
    item.setText(1, File.mtime(file).strftime(&quot;%Y-%m-%d %I:%M:%S %p&quot;))
    item.setText(2, (File.size(file).to_s + ' bytes'))
    item.setText(3, File.dirname(file) + '/')
    item.setIcon(0, Qt::Icon.new(File.ftype(file)) )

    #add item to the tree
    if (parent == nil)
      tree.addTopLevelItem(item)
    else
      parent.insertChild(parent.childCount, item)
    end

    if (File.ftype(file) == 'directory')
      populate(tree, file, item)
    end
  end
end

if $0 == __FILE__
  #parse command line
  if (ARGV.size &gt; 0)
    path = ARGV[0]
  else
    path = $DEFAULT_PATH
  end

  app = Qt::Application.new(ARGV)
  tree = Qt::TreeWidget.new
  tree.windowTitle = &quot;Simple Tree Example&quot;
  
  #set view headers
  tree.setHeaderLabels(['File Name', 'Last Modified', 'Size', 'Path'])
  populate(tree,path)
  
  tree.show
  app.exec
end</pre></div></div>
<p>Interesting bits and pieces of the code above include the import of the Qt4 library for ruby:-</p>
<p><code>require 'Qt4'</code></p>
<p>And the main Qt application execution:-</p>
<div class="hl-surround" ><div class="hl-main"><pre>app = Qt::Application.new(ARGV)
tree = Qt::TreeWidget.new
tree.windowTitle = &quot;Simple Tree Example&quot;
 
#set view headers
tree.setHeaderLabels(['File Name', 'Last Modified', 'Size', 'Path'])
populate(tree,path)
  
tree.show
app.exec</pre></div></div>
<p>Every Qt Application needs to create a Qt::Application object. In our simple example only one widget is used (the TreeWidget). Because we are calling to the widget&#8217;s default constructor it will be drawn in it&#8217;s own window. If we want to draw the widget inside a parent window, we should pass that parent window in the widget&#8217;s constructor.</p>
<p>We then set the headers of the table and populate the tree (see below). </p>
<p>By calling to <code>tree.show</code> we let Qt know that from now on the widget must be drawn. The last line transfers the execution control to the Qt engine.</p>
<p>To populate the tree we are using a recursive function. For every row we want to add to the view we create a Qt::TreeWidgetItem, populate its properties (mainly the text to be displayed in each column) and add it to the TreeWidget object. The code that handles the hierarchy is shown here:-</p>
<div class="hl-surround" ><div class="hl-main"><pre>#add item to the tree
if (parent == nil)
  tree.addTopLevelItem(item)
else
  parent.insertChild(parent.childCount, item)
end

if (File.ftype(file) == 'directory')
  #recursively browse through the filesystem
  populate(tree, file, item)
end</pre></div></div>
<p>Where we are using <code>TreeWidget.addTopLevelItem</code> or <code>TreeWidgetItem.insertChild</code> depending on whether we want to add a top level element or a child to a given item.</p>
<p>One last notice, the call:-<br />
<code>item.setIcon(0, Qt::Icon.new(File.ftype(file)))</code><br />
Sets the icon for the item&#8217;s first column. In this version the pictures are loaded from the filesystem, so you will need to have <a href="http://weblog.nomejortu.com/data/img/directory.png">directory.png</a> and <a href="http://weblog.nomejortu.com/data/img/file.png">file.png</a> in the execution directory.</p>
<p><strong>References</strong></p>
<ul>
<li><a href="http://doc.trolltech.com/4.0/classes.html">Summary of Qt4 classes</a></li>
<li><a href="http://doc.trolltech.com/4.0/qtreewidget.html">QTreeWidget API</a></li>
<li><a href="http://doc.trolltech.com/4.0/qtreewidgetitem.html">QTreeWidgetItem API</a></li>
</ul>
<img src="http://weblog.nomejortu.com/?ak_action=api_record_view&id=17&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.nomejortu.com/x-windows/ruby-qttreewidget-example/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>kde desktop background auto change</title>
		<link>http://weblog.nomejortu.com/shell-script/kde-desktop-background-auto-change</link>
		<comments>http://weblog.nomejortu.com/shell-script/kde-desktop-background-auto-change#comments</comments>
		<pubDate>Thu, 14 Dec 2006 11:21:26 +0000</pubDate>
		<dc:creator>etd</dc:creator>
				<category><![CDATA[Shell Script]]></category>
		<category><![CDATA[X Windows]]></category>

		<guid isPermaLink="false">http://weblog.nomejortu.com/?p=10</guid>
		<description><![CDATA[Much in the way we did with xfce here is the way to implement de auto change feature in KDE.
This is an easy one. Although you can perform background auto change from KDE control center, it may be usefull to have a script to do the task. You can use this script to create a [...]]]></description>
			<content:encoded><![CDATA[<p>Much in the way we did with <a href="http://weblog.nomejortu.com/?p=2">xfce</a> here is the way to implement de <em>auto change</em> feature in <a href="http://www.kde.org/">KDE</a>.</p>
<p>This is an easy one. Although you can perform background auto change from KDE control center, it may be usefull to have a script to do the task. You can use this script to create a link in your desktop to change the background image when you want.</p>
<p>The KDE applications can be controlled by scripts via the <a href="http://developer.kde.org/documentation/other/dcop.html">DCOP</a> mechanism. From the <a href="http://en.wikipedia.org/wiki/DCOP">Wikipedia</a>:</p>
<blockquote><p>
DCOP, which stands for Desktop COmmunication Protocol, is a light-weight interprocess and software componentry communication system. The main point of this system is to allow applications to interoperate, and to share complex tasks. Essentially, DCOP is a &#8216;remote control&#8217; system, which allows an application or a script to enlist the help of other applications. It is built on top of the X Window System&#8217;s Inter-Client Exchange protocol.</p></blockquote>
<p><span id="more-10"></span><br />
Let&#8217;s begin with the script, here is the <a href="http://weblog.nomejortu.com/data/code/bash/kde-desktop">code</a>:</p>
<div class="hl-surround" ><div class="hl-main"><pre>#!/bin/bash
dcop kdesktop KBackgroundIface changeWallpaper</pre></div></div>
<p>Now, you have to create a list of backgrounds using KDE&#8217;s control center. First open <code>kcontrol</code>, browse to  <code>Appearance &#038; Themes > Background</code> and select <code>Slide Show</code>. Click on <code>Settings</code></p>
<p><img src="http://weblog.nomejortu.com/data/img/kdebackgroundlist.jpg" alt="Slide Show Settings - list of backgrounds " /></p>
<p>Just create the list, and the script is ready to go.</p>
<img src="http://weblog.nomejortu.com/?ak_action=api_record_view&id=10&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.nomejortu.com/shell-script/kde-desktop-background-auto-change/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>xmms song in mail&#8217;s signature</title>
		<link>http://weblog.nomejortu.com/shell-script/xmms-song-in-mails-signature</link>
		<comments>http://weblog.nomejortu.com/shell-script/xmms-song-in-mails-signature#comments</comments>
		<pubDate>Sat, 12 Nov 2005 11:28:27 +0000</pubDate>
		<dc:creator>etd</dc:creator>
				<category><![CDATA[Shell Script]]></category>
		<category><![CDATA[X Windows]]></category>

		<guid isPermaLink="false">http://weblog.nomejortu.com/?p=5</guid>
		<description><![CDATA[We need three files for this:

signature.txt: you should point your mail client to this one
signature.tpl: here is the common text to display, something like &#8220;xmms is now playing:&#8220;
signature.sh: the script first copies the contents of the template file to the final signature file, and then adds the current song as a new line.


Download signature.sh:
#!/bin/sh
cat /home/etd/scripts/signature.tpl [...]]]></description>
			<content:encoded><![CDATA[<p>We need three files for this:</p>
<ul>
<li><strong>signature.txt:</strong> you should point your mail client to this one</li>
<li><strong>signature.tpl:</strong> here is the common text to display, something like &#8220;<em>xmms is now playing:</em>&#8220;</li>
<li><strong>signature.sh:</strong> the script first copies the contents of the template file to the final signature file, and then adds the current song as a new line.</li>
</ul>
<p><span id="more-5"></span><br />
Download <a href="http://weblog.nomejortu.com/data/code/bash/signature.sh">signature.sh</a>:</p>
<div class="hl-surround" ><div class="hl-main"><pre>#!/bin/sh
cat /home/etd/scripts/signature.tpl &gt; /home/etd/scripts/signature.txt
echo $1 &gt;&gt; /home/etd/scripts/signature.txt</pre></div></div>
<p>you only need to call the script using the <strong>change song</strong> xmms builtin plugin.</p>
<img src="http://weblog.nomejortu.com/?ak_action=api_record_view&id=5&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.nomejortu.com/shell-script/xmms-song-in-mails-signature/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>xfce desktop background auto change</title>
		<link>http://weblog.nomejortu.com/shell-script/xfce-desktop-background-auto-change</link>
		<comments>http://weblog.nomejortu.com/shell-script/xfce-desktop-background-auto-change#comments</comments>
		<pubDate>Mon, 19 Sep 2005 14:59:38 +0000</pubDate>
		<dc:creator>etd</dc:creator>
				<category><![CDATA[Shell Script]]></category>
		<category><![CDATA[X Windows]]></category>

		<guid isPermaLink="false">http://www.nomejortu.com/weblog/?p=2</guid>
		<description><![CDATA[First of all check Xfce 4 Desktop Manager help. Click on the New list&#8230; button and create a list with all the backgrounds you want to rotate.
From this page:
To refresh the backdrop with a new random image from the list just run the xfdesktop command again, e.g. from a terminal or the run dialog, or [...]]]></description>
			<content:encoded><![CDATA[<p>First of all check <a href="http://www.loculus.nl/xfce/documentation/docs-4.2/xfdesktop.html#xfdesktop-background">Xfce 4 Desktop Manager help</a>. Click on the <strong>New list&#8230;</strong> button and create a list with all the backgrounds you want to rotate.</p>
<p>From this page:</p>
<blockquote><p>To refresh the backdrop with a new random image from the list just run the <strong>xfdesktop</strong> command again, e.g. from a terminal or the run dialog, or <strong>xfdesktop</strong> [-reload].</p></blockquote>
<p>What we have to do now is to create a shell script that runs <code>xfdesktop -reload</code> and to add a cron job to run it.<br />
<span id="more-2"></span><br />
Let&#8217;s begin with the script, here is the <a href="http://weblog.nomejortu.com/data/code/bash/xfdesktop-reload">code</a>:</p>
<div class="hl-surround" ><div class="hl-main"><pre>#!/bin/bash

#check if we are under xfce
for foo in  `ps aux | grep xfdesktop | awk '{print $11}'`;
do
        if [ $foo == &quot;xfdesktop&quot; ];
        then
                #reload xfdesktop
                export DISPLAY=:0
                xfdesktop -reload
        fi;
done;</pre></div></div>
<p>Now we need to add a line in the crontab, run the script every 25 minutes:<br />
<code>*/25    *       *       *       *       /home/etd/scripts/xfdesktop-reload</code></p>
<p>NOTE: If someone finds an easier way to check wether the user is running Xfce or not, please let me know.</p>
<img src="http://weblog.nomejortu.com/?ak_action=api_record_view&id=2&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://weblog.nomejortu.com/shell-script/xfce-desktop-background-auto-change/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
