Sharing some thoughts on programming languages and gui toolkits.

Alain De Vos

Aspiring Daemon

Reaction score: 245
Messages: 958

Here the results of some tests did I with programming languages and gui toolkits,
First what works nicely,
ruby+tk/fox/gtk
python+tk/fltk/wxwidgets/gtk/qt
kotlin(java)+swing
charp+gtk
dlang+tk
dlang+gtk

Second what does not, work or i find ugly:
ada+gtk : ugly
go+gtk : broken
crystal+gtk : broken
nim+gtk : ugly
scala+swing : unsupported

Thought,
Alternative there is electron, popular but needs very much code, even to do something very simple.
I find a mix of html,css,javascript very ugly.
Feel free to elaborate or share your experiences.
 
Last edited:

Zirias

Daemon

Reaction score: 1,180
Messages: 2,129

Hm, why not C++/Qt (or, if you prefer, C/GTK)? I prefer C over C++, but Qt over GTK, so I end up using C++ for GUI applications.

Nice and perfectly portable (Win, Mac, Linux, *BSD, ...), just without the bullshit attached to electron 😈
 

BostonBSD

Active Member

Reaction score: 55
Messages: 119

I was going to post this somewhere else, but then I saw this.
I just learned how to make a really easy gui perl script with gtk3.
[any command line script can have a gui really really easily.]

This is an example script that gets the system time and sets it on a label.
I modified some code from a tutorial found here

Perl:
#!/usr/local/bin/perl
#Most of this code comes from a tutorial posted @ https://github.com/kevinphilp/Perl-gtk3-Tutorial
use strict;
use warnings;
use diagnostics;
use feature ':5.14';
use Gtk3 '-init';
use Glib qw/TRUE FALSE/;

#######Declarations

my $window = Gtk3::Window->new('toplevel'); #Creates a toplevel window
$window->set_title("Example Title"); #Sets the title
$window->set_position("center"); # Sets the starting location
$window->set_default_size(400, 300); # Sets the initial size
$window->set_border_width(5);
$window->signal_connect (delete_event => sub { Gtk3->main_quit }); #Exits Program When the Window Closes

my $button1 = Gtk3::Button->new("Quit"); #create a button
$button1->signal_connect(clicked => \&quit_function); #give the button functionality.
my $button2 = Gtk3::Button->new("Say Hello"); #create a button
$button2->signal_connect(clicked => \&say_something, "Hello"); #call a function, pass a string to the function.
my $button3 = Gtk3::Button->new("Get Time"); #create a button
$button3->signal_connect(clicked => \&get_time); #call a function.

my $hbox = Gtk3::Box->new("horizontal",5); #create a container for the buttons, the items are stacked horizontally, 5 pixels between them
$hbox->set_homogeneous (TRUE); #Allocate the same amount of space to each item, now all items are the same width.
$hbox->pack_start($button1, TRUE, TRUE, 0); #add a button to the container, expand the container to make space for the item, the expansion is filled with the item and not padding, 0 extra pixels of padding
$hbox->pack_start($button2, TRUE, TRUE, 0);
$hbox->pack_start($button3, TRUE, TRUE, 0);

my $vbox = Gtk3::Box->new("vertical",5); #create a container with items stacked vertically.
$vbox->add($hbox); #add the hbox container to the vbox container
my $label = Gtk3::Label->new("Am I connected?"); # create a label
$vbox->add($label);#add the label to the vbox container.

$window->add($vbox); #Add the vbox container to the main window.
$window->show_all; #Makes the window visible.

######functions
sub say_something {
    my ($button,$userdata) = @_;
    $label->set_label( $userdata );
    return TRUE;
}

sub get_time {
    my $time = `date \"+%r\"`; #get the system time.
    $label->set_label( $time ); # set the label
    return TRUE;
}

sub quit_function {
    say "Exiting Gtk3"; #say is no different from print
    Gtk3->main_quit;
    return FALSE;
}
############

Gtk3->main; #Tells perl to wait for user input.
 
OP
Alain De Vos

Alain De Vos

Aspiring Daemon

Reaction score: 245
Messages: 958

I never really used perl. I tried your script, it returns " Can't locate Gtk3.pm @ INC"
 

BostonBSD

Active Member

Reaction score: 55
Messages: 119

I never really used perl. I tried your script, it returns " Can't locate Gtk3.pm @ INC"
The Gtk3 and Glib modules need to be installed.

sudo cpan install Glib Gtk3

I'd like to find a tutorial for C/C++ and Gtk3 next.

I always like having at least one compiled language and one interpreted language ready.
Java is really useful for socket programming, but I still prefer C/C++ and Perl [python seems nearly equivalent to perl].

I would also keep my eye on rust. It has much greater ability to prevent garbage cleanup errors and seems to have nearly the same performance as C/C++ [this is an edit, but whatever benefits are found in other languages probably will make their way to C/C++ standardization eventually, rust compile time is reportedly longer with larger binaries].

If a language I already know can do it, that's better than using a language I do not already know [unless it become prohibitivly expensive to keep using the same language, which is why I would use java for sockets].
 
Last edited:

AlexanderProphet

Active Member

Reaction score: 42
Messages: 172

I love gtk+ it’s a superb piece of engineering and an absolute pleasure to work with. A good book focusing on C is “Foundations of Gtk+ Development” by Andrew Krause. I got it about ten years ago but it’s still surprisingly relevant. Occasionally you’ll get a deprecated function but Gtk+ is very good at warning you about these.
 

Jose

Aspiring Daemon

Reaction score: 751
Messages: 877

The Gtk3 and Glib modules need to be installed.

sudo cpan install Glib Gtk3
I'd rather use the package or the port

I'm allergic to running these platform-specific package managers as root, and having them pee all over my filesystems.
 

BostonBSD

Active Member

Reaction score: 55
Messages: 119

I'd rather use the package or the port

I'm allergic to running these platform-specific package managers as root, and having them pee all over my filesystems.
I never even considered that. I never knew that was a problem.
 

Beastie7

Aspiring Daemon

Reaction score: 450
Messages: 605

I love gtk+ it’s a superb piece of engineering and an absolute pleasure to work with. A good book focusing on C is “Foundations of Gtk+ Development” by Andrew Krause. I got it about ten years ago but it’s still surprisingly relevant. Occasionally you’ll get a deprecated function but Gtk+ is very good at warning you about these.

You can't be serious.
 

garry

Active Member

Reaction score: 92
Messages: 106

Here the results of some tests did I with programming languages and gui toolkits,
First what works nicely,
...
python+qt : One of the rare qt bindings which works fine.
python+Qt: I'm coming around to agree with this one. I installed helloSystem / FreeBSD 13 and the interface achieved with Qt and Python is impressive in its simplicity and usability. I think probono is on to something good there.
 
OP
Alain De Vos

Alain De Vos

Aspiring Daemon

Reaction score: 245
Messages: 958

Qt has some very interesting widgets not found in Gtk. I find it superior, but it's language bindings are poor. So for Qt there is only C++ or Python.
I wonder will fox, fltk, wxwidgets survive as toolkits, or die ?
 

BostonBSD

Active Member

Reaction score: 55
Messages: 119

Here's a C program that does exactly the same thing as that perl script {I just learned this, i figured I'd post it}. Perl is faster and easier to program, perhaps not as efficient though.


C:
#include <stdio.h>
#include <stdlib.h>
#include <gtk/gtk.h>


GtkBuilder *builder;

static void
print_time (GtkWidget *widget,
             gpointer   data)
{
    GObject *label;
    label = gtk_builder_get_object (builder, "label1"); //get the label1 GObject from the builder
   
    ///////////////////////////////////////Run A Command and Get the Output
    FILE *file_pointer;
    char variable[256];

    /* Open the command for reading. */
    file_pointer = popen("/bin/date \"+%r\"", "r");
    if (file_pointer == NULL) {
        printf("Didn't Work\n" );
        exit(1);
    }

    // Read in one line of file_pointer to variable
    fgets(variable, sizeof(variable), file_pointer);
     /* close */
    pclose(file_pointer);
    ///////////////////////////////////////I found this portion from a bing search.
   
    //set the label.
    g_object_set (label,"label",variable,NULL);  //a GObject, Property Name, Property Value, NULL indicates no further properties to parse.

 
}

static void
print_hello_label (GtkWidget *widget,
             gpointer   data)
{
    GObject *label;
    label = gtk_builder_get_object (builder, "label1");
    g_object_set (label,"label","Hello World!",NULL);
}

int
main (int   argc,
      char *argv[])
{
  GObject *window;
  GObject *button;
  GError *error = NULL;

  gtk_init (&argc, &argv);

  /* Construct a GtkBuilder instance and load our UI description */
  builder = gtk_builder_new ();
  if (gtk_builder_add_from_file (builder, "builder.ui", &error) == 0)
    {
      g_printerr ("Error loading file: %s\n", error->message);
      g_clear_error (&error);
      return 1;
    }

  /* Connect signal handlers to the constructed widgets. */
  window = gtk_builder_get_object (builder, "window");
  g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);

  button = gtk_builder_get_object (builder, "button1");
  g_signal_connect (button, "clicked", G_CALLBACK (print_time), NULL);

  button = gtk_builder_get_object (builder, "button2");
  g_signal_connect (button, "clicked", G_CALLBACK (print_hello_label), NULL);

  button = gtk_builder_get_object (builder, "quit");
  g_signal_connect (button, "clicked", G_CALLBACK (gtk_main_quit), NULL);

  gtk_main ();

  return 0;
}

The user interface is setup with an XML file, it should be called "builder.ui" and in the same directory as the binary file.


XML:
<interface>
  <object id="window" class="GtkWindow">
    <property name="visible">True</property>
    <property name="title">Grid</property>
    <property name="window-position">center</property>
    <property name="default-width">400</property>
    <property name="default-height">300</property>
    <property name="border-width">5</property>
    <child>
    <object id="vbox" class="GtkBox">
        <property name="homogeneous">True</property>
        <property name="visible">True</property>
        <property name="orientation">vertical</property>
        <property name="vexpand-set">True</property>
        <property name="vexpand">True</property>
        <child>
        <object id="hbox" class="GtkBox">
            <property name="homogeneous">True</property>
            <property name="visible">True</property>
            <property name="orientation">horizontal</property>
            <property name="hexpand-set">True</property>
            <property name="hexpand">True</property>
            <child>
            <object id="button1" class="GtkButton">
                <property name="visible">True</property>
                <property name="label">Get Time</property>
            </object>
            <packing>
                <property name="expand">True</property>
            </packing>
            </child>
            <child>
            <object id="button2" class="GtkButton">
                <property name="visible">True</property>
                <property name="label">Say Hello</property>
            </object>
            <packing>
                <property name="expand">True</property>
            </packing>
            </child>
            <child>
            <object id="quit" class="GtkButton">
                <property name="visible">True</property>
                <property name="label">Quit</property>
            </object>
            <packing>
                <property name="expand">True</property>
            </packing>
            </child>
        </object>
        <packing>
        </packing>
        </child>
        <child>
        <object id="label1" class="GtkLabel">
            <property name="visible">True</property>
            <property name="label">Am I Connected?</property>
        </object>
        </child>
    </object>
    <packing>
    </packing>
    </child>
  </object>
</interface>


To Compile:
gcc `pkg-config --cflags gtk+-3.0` -o gtk_example gtk_example.c `pkg-config --libs gtk+-3.0`

assuming the source file is called "gtk_example.c"

I don't really think it matters what the language is, all that matters is the gui library. GTK and QT look the same no matter if it's C, C++, Python or Perl....so far as I can tell.
 

Zirias

Daemon

Reaction score: 1,180
Messages: 2,129

I'm not a huge fan of declarative UI descriptions, my Qt UIs are all built programmatically ;) But then, I guess GTK would support that as well. Anyways, BostonBSD, this tiny example looks pretty readable and self-explanatory. Maybe I should give GTK another look, it's intriguing to have a GUI in plain C. Last time I did that, it was for Windows, using native win32 API. Now, THAT's really mind-boggling :D
 

BostonBSD

Active Member

Reaction score: 55
Messages: 119

I'm not a huge fan of declarative UI descriptions, my Qt UIs are all built programmatically ;) But then, I guess GTK would support that as well. Anyways, BostonBSD, this tiny example looks pretty readable and self-explanatory. Maybe I should give GTK another look, it's intriguing to have a GUI in plain C. Last time I did that, it was for Windows, using native win32 API. Now, THAT's really mind-boggling :D
I saw that it can be built in programmatically from the gtk website, although they suggested using an XML file if only because the UI can be changed after compile time if need be [its also possible to compile the XML data into the binary as a string]. They also said something about using glade to design your own UI, which then generates its own XML file.

It is really intriguing that a GUI can be made in plain C. Thanks for the nice comments :) .
 

kpedersen

Son of Beastie

Reaction score: 1,673
Messages: 2,507

I'm not a huge fan of declarative UI descriptions, my Qt UIs are all built programmatically

Agreed. There is the argument for not mixing controller, view and model. However my response to that is yes, but there is no reason to use a different language or markup in doing so.

I am quite a big fan of wxWidgets. The fact that it abstracts many other toolkits means that it will likely have a very good lifespan. I.e it gets "free" Wayland support by proxy of supporting Gtk+ as a backend.
 
OP
Alain De Vos

Alain De Vos

Aspiring Daemon

Reaction score: 245
Messages: 958

I trie to avoid xml & editors/guis/builders.
Any ideas on dart ? or swt/eclipse ?

Something else. Here a ruby+fox toolkit fahrenheit to celcius converter,
Code:
#!/usr/local/bin/ruby
require 'fox16'
include Fox

class MyMainWindow < FXMainWindow
    def initialize(app)
        super(app, "Convertor", :width => 400, :height => 200)
        entry=FXTextField.new(self,20)
        button=FXButton.new(self, "Convert")
        label=FXLabel.new(self, "_________")
    
        button.connect(SEL_COMMAND) do
            fs=entry.text
            f=fs.to_f
            c=(f-32.0)*5.0/9.0
            cs=c.to_s
            label.text=cs
        end
    end

    def create
        super
        show(PLACEMENT_SCREEN)
    end
end

if __FILE__ == $0
    FXApp.new do |app|
        MyMainWindow.new(app)
        app.create
        app.run
    end
end
 

Zirias

Daemon

Reaction score: 1,180
Messages: 2,129

Agreed. There is the argument for not mixing controller, view and model. However my response to that is yes, but there is no reason to use a different language or markup in doing so.
Well about that: I think MVC is a great concept for dealing with web applications, cause, if your rendering target (the browser) expects markup, it comes naturally to use markup to describe your view. Still I prefer implementations that actually compile these views and link them to the binary. For "desktop" UIs, I'm fine with just the dusty old presentation layer done in code. Business logic is clearly separated in any case, enough separation of concerns for me ;)

I am quite a big fan of wxWidgets. The fact that it abstracts many other toolkits means that it will likely have a very good lifespan. I.e it gets "free" Wayland support by proxy of supporting Gtk+ as a backend.
IMHO having yet another abstraction layer was more useful in the past, nowadays I see little reason not to use Qt or GTK directly, as both support lots of "native" display solutions on many platforms…
 

kpedersen

Son of Beastie

Reaction score: 1,673
Messages: 2,507

IMHO having yet another abstraction layer was more useful in the past, nowadays I see little reason not to use Qt or GTK directly, as both support lots of "native" display solutions on many platforms…

Qt is pretty stable (Though MOC still makes me shudder) but Gtk I don't really want to be updating every ~5 years. I am maintaining a version of GtkRadiant and am still stuck at Gtk+2.x because of a large number of changes required to update it to the latest (actually half way through porting it to wxWidgets :)).
 
Top