Thursday Night

Paul Betts’s personal website / blog / what-have-you

Archive for the ‘QT/KDE’ Category

Qt4 Ruby and Metaprogramming 0.1 – Wiring up slots automatically

7 comments

In my attempts to learn Qt 4 and QtRuby, it’s pretty obvious that there’s a huge potential for doing Rails-like things, such as declaration by convention. To this end, here’s an example of what you can do with the code I’m writing: this loads a UI file and wires something up to the Open action:

require ‘Qt’

class ActionOpenHandler < Qt::Object
    slots "on_activated()"

    def initialize(main = nil)
        super
        @main = main
    end

    def on_activated
        path = nil
        Qt::FileDialog.new do |fd|
            path = fd.get_open_file_name()
        end
        return unless path

        text = nil; File.open(path, ‘r’) {|f| text = f.read}
        @main.findChild(Qt::TextEdit, "textBrowser").text = text
    end
end

a = Qt::Application.new(ARGV)
QtSuperLoader.new.initialize_and_hook("./main.ui").show
a.exec

Next, I’m seeking to replace the ugly line "@main.findChild(Qt::TextEdit, "textBrowser").text = text" with the more palatable "@main.text_browser.text = text". However, this is a bit more tricky, because findChild creates strongly-typed objects – there may be some trickery to get around it though involving QMetaObject.

Here’s the files, including the code that supports it all: qttest.rb and Translator.ui

Written by Paul Betts

September 8th, 2007 at 10:20 pm

Posted in QT/KDE, Ruby

Don’t worry, I haven’t forgotten QtRuby on Win32!

I was planning on posting the same kind of tutorial for Win32 for using QtRuby, but I’m currently stuck as to how to get it to build. After fighting with random build glitches for three hours or so (making progress, slowly), I’m currently stuck here:

Compiled with:
C:/MinGW/bin/g++.exe   -IC:/Qt/4.3.0/include/QtDBus -IC:/Qt/4.3.0/include/QtTest
 -IC:/Qt/4.3.0/include/QtUiTools -IC:/Qt/4.3.0/include/QtScript -IC:/Qt/4.3.0/in
clude/QtSvg -IC:/Qt/4.3.0/include/QtXml -IC:/Qt/4.3.0/include/QtSql -IC:/Qt/4.3.
0/include/QtOpenGL -IC:/Qt/4.3.0/include/QtNetwork -IC:/Qt/4.3.0/include/QtDesig
ner -IC:/Qt/4.3.0/include/QtDesigner -IC:/Qt/4.3.0/include/QtAssistant -IC:/Qt/4
.3.0/include/Qt3Support -IC:/Qt/4.3.0/include/QtGui -IC:/Qt/4.3.0/include/QtCore
 -IC:\Qt\4.3.0\mkspecs/default -IC:/Qt/4.3.0/include/Qt -IC:/Qt/4.3.0/include  C
:/Qt/4.3.0/lib/libQtCore4.a C:/Qt/4.3.0/lib/libQtNetwork4.a C:/Qt/4.3.0/lib/libQ
tSql4.a C:/Qt/4.3.0/lib/libQtXml4.a C:/Qt/4.3.0/lib/libQtGui4.a C:/Qt/4.3.0/lib/
libQtUiTools.a C:/Qt/4.3.0/lib/libQtSvg4.a C:/Qt/4.3.0/lib/libQtOpenGL4.a C:/Qt/
4.3.0/lib/libQt3Support4.a  -o C:\Users\paulbe\AppData\Local\Temp/3428-qtguess C
:\Users\paulbe\AppData\Local\Temp/3428-qtguess.cpp
Compiler output:
C:\Users\paulbe\AppData\Local\Temp/3428-qtguess.cpp:8:2: warning: no newline at
end of file
C:\Users\paulbe\AppData\Local\Temp/ccMxaaaa.o(.text+0×147):3428-qtguess.cpp:
undefined reference to `_imp___ZN12QApplicationC1ERiPPci
C:\Users\paulbe\AppData\Local\Temp/ccMxaaaa.o(.text+0×154):3428-qtguess.cpp:
undefined reference to `QApplication::~QApplication()’

collect2: ld returned 1 exit status

Thoughts? It looks like I’ve got some sort of compiler mismatch (one library compiled with MSVC and one compiled with MinGW, probably). I have no idea where though, I’m 85% sure that Qt is compiled with MinGW

Update: Alright, the new plan is to compile everything from scratch, and see if I can get some better results.

Update 2: It’s definitely the compiler difference:

> objdump -x C:\Qt\4.3.0\lib\libQtGui4.a

{ Snip! }

SYMBOL TABLE:
[  0](sec  1)(fl 0×00)(ty   0)(scl   3) (nx 0) 0×00000000 .text
[  1](sec  2)(fl 0×00)(ty   0)(scl   3) (nx 0) 0×00000000 .idata$7
[  2](sec  3)(fl 0×00)(ty   0)(scl   3) (nx 0) 0×00000000 .idata$5
[  3](sec  4)(fl 0×00)(ty   0)(scl   3) (nx 0) 0×00000000 .idata$4
[  4](sec  5)(fl 0×00)(ty   0)(scl   3) (nx 0) 0×00000000 .idata$6
[  5](sec  1)(fl 0×00)(ty   0)(scl   2) (nx 0) 0×00000000 __ZN12QApplicationC2ERiPPci
[  6](sec  3)(fl 0×00)(ty   0)(scl   2) (nx 0) 0×00000000 __imp___ZN12QApplicationC2ERiPPci
[  7](sec  0)(fl 0×00)(ty   0)(scl   2) (nx 0) 0×00000000 __head_QtGui4_dll

The compiler’s looking for __imp___ZN12QApplicationC1ERiPPci, but the precompiled library has C2. I don’t understand why Qt’s distributing a busted library – this would break even their samples in straight C++ – it’s possible that Mingw updated behind their back though.

Written by Paul Betts

July 22nd, 2007 at 8:32 pm

Posted in Microsoft, QT/KDE, Ruby

Cross-platform UI with Qt4 and Ruby – Mac/Linux HOWTO

16 comments

Today I’ve spent the day working on figuring out how to make UIs using Ruby and Qt4. If you haven’t heard of it, Qt4 is an awesome UI framework written in C++. Since C++ is way too much work, some great KDE devs wrote a bindings generator for Qt4 called qt4-qtruby. While this package is fairly “linuxy”, it’s pretty easy to build it on Mac OS X too, making it possible to write GUI programs for OS X without having to delve into RubyCocoa which has too much hackiness (in my opinion), or even worse, Objective C. Furthermore, your code that you write on OS X will look great on Windows and Linux too!

Starting from scratch

First, install Ruby. If you’re using Linux, you’ll probably use the package manager to install Ruby and the Ruby development libraries! (Ubuntu will run sudo apt-get install ruby irb ruby-dev) OS X Tiger ships with Ruby by default, but you’ll want to install an updated version, via the Ruby one-click installer, then disable the old Ruby by using the following command:

## Only do this on Mac! Linux doesn’t need this nonsense ##
touch ~/.bashrc && echo ‘export PATH="/usr/local/bin:$PATH"’ >> ~/.bashrc
sudo mv /usr/lib/libruby.1.dylib /usr/lib/_libruby.1.dylib

Installing Qt4 and QtRuby

First, install Qt4 by using your package manager on Linux (in Ubuntu, use the -kdecopy packages, they are more up to date), or by downloading the DMG from the Qt/Mac Open Source Edition Download page. You’ll also need MacPorts (and by proxy, the XCode tools). Also, download the Qt4 Ruby bindings source code from Rubyforge and save it to the Desktop.

Here’s the cool thing about QtRuby, and the advantage of building it from source: the build framework for QtRuby scans through whatever version of Qt you have installed, and dynamically builds the bindings. This means, there’s no waiting for new Qt features to be available in Ruby, it’s always up-to-date! Which is quite handy, because it seems like every minor version of Qt has new cool stuff.

Next, we have to do a bit of hackery – unfortunately, there’s no easy way to install QtRuby but it’s not so hard. Here’s what you’ll run:

cd ~/Desktop
sudo port install cmake   ## CMake is a cool build system
tar -xzvf qt4-qtruby-1.4.9.tgz && cd ./qt4-qtruby-1.4.9
cmake .
make && sudo make install

Try it out!

Once you’ve got it built, try this sample code to see some of the new features in Qt 4.3 – this code will run a natively-styled wizard in Windows, Mac, and Linux without any changes! Unfortunately, this code isn’t very elegant or Ruby-like, but it’s a base that someone could write a really elegant UI framework over like RoR.

require ‘Qt’
a = Qt::Application.new(ARGV)

def create_intro_page
        page = Qt::WizardPage.new do |p|
                p.title = "Introduction"
        end

        label = Qt::Label.new("This is a wizard!")
        label.word_wrap = true
        layout = Qt::VBoxLayout.new do |v|
                v.add_widget(label)
        end
        page.layout = layout
        page
end

wiz = Qt::Wizard.new do |x|
        x.add_page(create_intro_page())
        x.set_window_title("Test Wizard")
        x.show
end

a.exec


On Mac OS X

On Linux

In summary:

  1. Install a Ruby that doesn’t suck, and hack your environment so it works right
  2. Install Qt and MacPorts
  3. Build QtRuby and install it
  4. Make UIs for all 3 platforms without hating your life

Written by Paul Betts

July 22nd, 2007 at 6:03 pm

Posted in Apple, Linux, Microsoft, QT/KDE, Ruby

Autotorrent 0.5.1 – This one is actually useful

8 comments

After reading the feedback on kde-apps.org as well as discovering how awesome KTorrent is, I’ve added some features to Autotorrent that should make it much more useful for people. First, I added support for other torrent programs, and I was able to make the KTorrent support really nice using DCOP. Basically, it means that once you have a default directory set up, Autotorrent can silently add torrents without popping up the “OMG DO YOU WANT TO SAVE THIS?!” dialog.


This dialog isn’t very pretty but that’s alright

Next, after learning some basic QtRuby, I managed to make a decent configuration dialog. It’s not very well spaced and it was a giant pain-in-the-ass to get what I wanted done, probably because I’m used to the GTK+ way of doing things, particularly when it comes to signals and slots. I’m totally biased, but I think the Qt way just involves a lot of extra declarations and isn’t nearly as Ruby-like as Ruby-GNOME2

Update: PS here’s where you can download Autotorrent. Oops.

Written by Paul Betts

February 24th, 2007 at 2:38 pm

Posted in Linux, QT/KDE, Ruby

Porting apps to KDE4 – part 1

2 comments

After reading all the awesome things about the new cool things in QT4, especially the graphics stuff, I decided to check it out. And what better way to learn a new technology than to contribute something to the community! So after Emailing the original author and making sure he wasn’t working on it himself, I started to work to port Filelight, a handy utility that lets you view your disk usage visually in a way that’s very easy to get useful information out of. The other thing that is exciting about KDE4 is apps “by default” work with Windows too, so in the near future we’ll see a flood of awesome new open source programs for Windows.

The first thing you should do when porting a KDE app is get your environment set up. I did this by going to the building from SVN guide and following the instructions. Some notes:

  • The guide says to create a separate user, but I think that’s overkill and somewhat annoying. What I did instead was create a script called kde_dev.sh that has the entries that they put into your .bashrc
  • Ubuntu Edgy (and most other distros) have a version of D-Bus that’s up to date enough, don’t bother compiling your own (it’ll give you massive headaches trying to get it to cooperate with your system’s D-Bus anyways)
  • Originally, I tried to use the Ubuntu KDE4 stuff that’s in Synaptic but unfortunately something’s glitched with building projects, cmake will always give you weird errors

Next, since Filelight uses Autotools, I could use the handy am2cmake script to create all of the CMakeFiles.txt entries automagically. It’s kind of cheating, but on the other hand, why should I have to look up a bunch of obscure commands unless I have to? I think I can get the Zeitgeist of cmake by reading the generated files. I also had to create a dummy ConfigureChecks.cmake which I’ll have to redo manually using the configure.ac file

After that, I read the Qt 4 Porting Guide and proceeded to cheat even more and use the qt3to4 utility to convert most of the code to Qt 4. However, after I get it to build correctly I’m going to go back and do a proper port, removing all of the old Qt3′isms.

References:

Written by Paul Betts

December 6th, 2006 at 10:47 am

Posted in QT/KDE