Jun 04 2007
ruby Qt custom widget example
With Qt’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 internal history of the widget and will be accessible by means of Up and Down arrows as the standard *nix command line.
Here is the code:-
=begin
**
** commandline.rb
** 03/JUN/2007
** ETD-Software
** - Daniel Martin Gomez <etd[-at-]nomejortu.com>
**
** 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 < 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 > 0) && (@pointer >= 0) )
if (@pointer == @history.size)
@history << self.text
end
@pointer -= 1 if @pointer > 0
self.text = @history[@pointer]
end
return
when Qt::Key_Down:
if ((@history.size > 0) && (@pointer < @history.size) )
@pointer += 1 if @pointer < @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 > 0) && (@history.last.strip.size == 0) )
@history.pop
end
if self.text.strip.size > 0
@history << 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
endAs you can see, out widget inherits from standard Qt LineEdit widget:-
class CommandLine < Qt::LineEdit
When instancing a copy of the widget we set up two variables to handle the internal history:-
def initialize(parent=nil) super(parent) #initialize internal history buffer @history = [] @pointer = 0 end
@history array contains the list of commands typed by the user. @pointer is a pointer to the element of the list that will be displayed when Up or Down keys are pressed.
All the widget’s functionality is coded in the keyPressEvent 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: Qt::Key_Up, Qt::Key_Down and Qt::Key_Return.
when Qt::Key_Up:
if ((@history.size > 0) && (@pointer >= 0) )
if (@pointer == @history.size)
@history << self.text
end
@pointer -= 1 if @pointer > 0
self.text = @history[@pointer]
end
returnIf the @history contains elements and the Qt::Key_Up is pressed we move the pointer to the correct place in the @history 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 @history before continuing.
when Qt::Key_Down:
if ((@history.size > 0) && (@pointer < @history.size) )
@pointer += 1 if @pointer < @history.size - 1
self.text = @history[@pointer]
end
returnLikewise, if the Down arrow is pressed we move the @pointer down the list and replace the text.
The last case when we intercept the KeyPress event is when the user hits the Return key. The first if gets rid of the last element of the @history if it is empty. Reme,ber when we added the current line to the history in the Qt::Key_Up case? This if removes that element if it was an empty line.
when Qt::Key_Return:
#keep an eye on the last entry to avoid empty entries in the list
if ((@history.size > 0) && (@history.last.strip.size == 0) )
@history.pop
end
if self.text.strip.size > 0
@history << self.text
@pointer = @history.size
self.clear
else
return
endWe 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 return, so no keyPressed() signal is raised.
The script contains helper code to test it by creating a Qt application and showing the widget.
Popularity: 9% [?]
