Setting up Qyoto on Mac OSX Lion

Vivek Gani - 30. September 2013

NOTE: This is an archived post originally written around August 2012. As a tl;dr of my personal opinion, I tend to recommend folks towards investing the effort into doing UI natively or with native wrappers (such as monomac)

I recently got curious how the c# and qt bindings (a.k.a. qyoto) worked, partly for a personal idea, partly because I’ve always wondered how effective it would be to make a good cross-platform app without writing in c++. I had some hiccups along the way and figured it was worth documenting my installation setup.

Setting Qt, Mono, and Qyoto up

0) If you don’t have homebrew setup on your mac already, go install homebrew / xcode / xcode console utilities.

1) Install qt (64-bit) via homebrew:

$ brew install qt

2) Install mono (64-bit) via homebrew. The usual binaries on the mono website are 32-bit still which won’t work with 64-bit qt libs.Thankfully you can build a 64-bit version easily via homebrew using adamv’s homebrew keg. 2013 update: adamv’s keg doesn’t exist - you likely want to use this one

$ brew tap adamv/alt
$ brew install mono

I recommend doing this over, say, compiling the 32-bit version of qt which will be nearly impossible on lion unless you recompile it’s other dependencies (e.g. mysql) as 32-bit too.

3) Now compile qyoto and it’s dependencies. The qyoto bindings work by generating assembly libraries based on the qt smoke.

First grab those sources:

$ git clone git://anongit.kde.org/smokegen
$ git clone git://anongit.kde.org/smokeqt
$ git clone git://gitorious.org/assemblygen/assemblygen.git

Then compile smokegen

$ cd smokegen
$ cmake -D "CMAKE_OSX_ARCHITECTURES:STRING=x86_64" .
$ make install

compile smokeqt

$ cd smokeqt
$ cmake -DSmoke_DIR="$PWD/../smokegen/cmake" .
$ make install

and compile qyoto

$ cd qyoto
$ cmake -D "CMAKE_OSX_ARCHITECTURES:STRING=x86_64" .
$ make install

You should now have qyoto compiled and installed in /usr/local/lib/mono/qyoto .

Running tutorial apps.

To compile a basic qyoto-based app, you’ll just compile and run it like this:

$ dmcs -r:/usr/local/lib/mono/qyoto/qyoto-qtgui.dll app.cs
$ mono app.exe

Below are a few examples based on the zetcode tutorial modified for use with the latest revision of the assemblygen based qyoto. Notable changes are that single value Get/Set methods are converted into accessors, while multi-parameter Get/Set methods are still functions for now.

A ‘hello window’ demo:

using System;
using Qyoto;

/**
 * ZetCode Qyoto C# tutorial
 *
 * This program centers a window
 * on the screen
 *
 * @author Jan Bodnar
 * website zetcode.com
 * last modified April 2012
 */


public class QyotoApp : QWidget {

    const int WIDTH = 250;
    const int HEIGHT = 150;

    public QyotoApp() {

        WindowTitle = "Center";

        QDesktopWidget qdw = new QDesktopWidget();

        int screenWidth = qdw.Width;
        int screenHeight = qdw.Height;

        int x = (screenWidth - WIDTH) / 2;
        int y = (screenHeight - HEIGHT) / 2;

        Resize(WIDTH, HEIGHT);
        Move(x, y);
        Show();
    }


    public static int Main(String[] args) {
        new QApplication(args);
        new QyotoApp();
        return QApplication.Exec();
    }
}

A tooltip demo:

using System;
using Qyoto;

/**
 * ZetCode Qyoto C# tutorial
 *
 * This program displays a
 * tooltip.
 *
 * @author Jan Bodnar
 * website zetcode.com
 * last modified April 2012
 */


public class QyotoApp : QWidget {

    public QyotoApp() {

        //QMessageBox q = new QMessageBox();

        WindowTitle = "Tooltip";

        ToolTip = "This is QWidget";    
        Resize(250, 150);
        Move(300, 300);
        Show();

        //q.Open();
    }


    public static int Main(String[] args) {
        new QApplication(args);
        new QyotoApp();
        return QApplication.Exec();
    }
}

A basic button demo:

using System;
using Qyoto;

/**
 * ZetCode Qyoto C# tutorial
 *
 * This program creates a quit
 * button. When we press the button,
 * the application terminates. 
 *
 * @author Jan Bodnar
 * website zetcode.com
 * last modified April 2012
 */


public class QyotoApp : QWidget {

    public QyotoApp() {

        WindowTitle = "Quit button";

        InitUI();

        Resize(250, 150);
        Move(300, 300);
        Show();
    }

    public void InitUI() {

        QPushButton quit = new QPushButton("Quit", this);

        Connect(quit, SIGNAL("clicked()"), qApp, SLOT("quit()"));
        quit.SetGeometry(50, 40, 80, 30);

    }

    public static int Main(String[] args) {
        new QApplication(args);
        new QyotoApp();
        return QApplication.Exec();
    }
}

Should you bother using Qyoto?

I’d say if you’re writing some basic form-based app that needs to be cross-platform, no, make a webapp. If you’re trying to write something like an engineering tool (e.g. a cross-platform IDE) and have limited resources, it may be useful.

The other potential issue with qyoto is the licensing. The generated assemblies of it are lgpl (the source is gpl). While this is okay to use for desktop apps, it’s an debatable position if you’re planning to bundle everything for iOS or android. Other qt-based frameworks such as kivy have had success with such efforts, but at the end of the day I usually tend to appreciate apps that use native ui frameworks, with games being the exception. That said, I’ve also been playing with monomac which is actively supported by xamarin.

References

Jeff Alstadt’s Guide to using qyoto on linux

Qyoto on KDE.org

Zetcode Qyoto Tutorial

Finally, a super huge thanks to Dimitar Dobrev for his support on the kde-bindings mailing list. He fixed a number of compile issues I was totally lost on fixing.

If you see anything wrong, feel free to comment below.