Author Topic: How To Incorporate a GUI in C  (Read 9726 times)

0 Members and 1 Guest are viewing this topic.

Offline bostonmanTopic starter

  • Super Contributor
  • ***
  • Posts: 1794
  • Country: us
How To Incorporate a GUI in C
« on: December 20, 2023, 04:11:48 am »
I have a question about C. Being aware of C and having done a few basic programs (i.e. I'm a novice), I asked someone about a very basic compiler that didn't require lots of setting up. He recommended GCC Compiler For Windows which seems to suit my needs well.

Unlike when I tried Visual Studio years ago, I don't need to change several settings and still get compiling issues for programs I know are correct. GCC seems to compile very easy and the few programs I've run compile without needing to wonder if a setting needs to be changed. It has a few drawbacks such as being command line based, having to type the program in Notepad++ , etc... but still, it's decent.

My question is: how can I incorporate a GUI into C?

From reading, I see gtk2-runtime-2.24.10-2012-10-10-ash is something that allows a GUI to be used with GCC, however, I'm not having much luck. I've entered a program the website provided, but get compiling errors.

Also, the reading I've done shows any available GUIs for C are very basic. If so, since GUIs are used in Windows (and Linux), does this mean C++ needs to be incorporated into a C program (as a library?) to have a nicer GUI?
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11262
  • Country: us
    • Personal site
Re: How To Incorporate a GUI in C
« Reply #1 on: December 20, 2023, 04:50:05 am »
Anything that is not "basic" will take time to figure out. If you stop at "it gives me errors", you will not go far. Read the errors and figure what they mean, then fix them.

GTK is a full framework, it is big and complicated. For simpler things you can use something like ImGUI or even direct WinAPI calls.

GUIs always suck, there is no one "easy" solution, it all depends on your needs. This is why a lot of new software just uses Electron or similar web-based UIs.

Also, you are confusing IDEs and compilers. Visual Studio is an IDE and the compiler it uses is also command line. You can install any IDE that and use that with GCC. Eclipse is a common option, although more and more people move to VSCode.
« Last Edit: December 20, 2023, 04:54:20 am by ataradov »
Alex
 

Offline bostonmanTopic starter

  • Super Contributor
  • ***
  • Posts: 1794
  • Country: us
Re: How To Incorporate a GUI in C
« Reply #2 on: December 20, 2023, 05:25:13 am »
Quote
Anything that is not "basic" will take time to figure out. If you stop at "it gives me errors", you will not go far. Read the errors and figure what they mean, then fix them.

You're correct and I did devote time to working through them. What I meant was that I was spending more time trying to figure out Visual Studio than errors in my C program; or I was questioning whether it was the program or VS for compiling errors.

I am confusing IDEs and compilers for the most part, but I also thought they were a compliment of each other. As an example, I thought I can't use VS without using its compiler. I may be totally wrong, but getting back to not being able to figure out errors, VS seemed to compile my C programs as it would C++ (or maybe some other programming language), so it spit out errors. When I thought the settings were all correct, I would still get compiling errors even though I copied the programs from online or a book and somewhat gave up.

As for my intent with C, I've always had a desire to expand my knowledge, but find anything basic (like Hello World, performing math, or if statements) to be somewhat "mastered" while the more complicated ones get way more involved.

Years ago a co-worker gave me a development kit that used a micro on a thumbdrive. Apparently it involved the ability to program it in C. I never grasped the concept of how to write (I'm exchanging a bit here) "Hello World" onto an IC chip. I also thought this was jumping into the deep end too quickly. The times I've tinkered with C, I try a basic (maybe) for statement and expand on it. I run it and see what happens, expand on that, and see what happens.

I thought the idea of a basic compiler like GCC and a basic GUI may help visualize what is happening. One program I had in mind was to utilize my resistor collection.

I have several value resistors, and, when it comes time to needing a value I don't have, I begin looking into using different values in series/parallel to achieve the desired value. I thought of writing a program that will take all my values, and perform a series of calculations that would spit out a a combination based within a percentage of my needed value. As an example: I tell it to calculate based on three resistors, the program takes all the values I've listed, and calculates several in a series or parallel and a series/parallel combination until it comes within x% (a value I set) of the value I need.

While this doesn't need a GUI, and although I thought this program may be useful, I believe it's more about the method of performing the calculations rather than actually learning C, so I never pursued the idea. The GUI was something I thought would be cool to click a button and have it perform a step, expand on that, blah blah.



 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11262
  • Country: us
    • Personal site
Re: How To Incorporate a GUI in C
« Reply #3 on: December 20, 2023, 05:50:19 am »
As an example, I thought I can't use VS without using its compiler.
Well, yes, VS is specifically designed for one compiler. But you can use the compiler on its own without the VS.

I would still get compiling errors even though I copied the programs from online or a book and somewhat gave up.
C is not some magic universal language. If you copy some example for Linux, it is mot likely to compile on Windows. You may also be missing some libraries.

I thought the idea of a basic compiler like GCC and a
GCC is not a "basic" compiler. It is literally one of the leading compilers currently available.


Long story short - read the errors. You can't "think" your way though correctness of compiler settings. If something does not compile,  you have something setup incorrectly. Or the code is just broken.

For quick and simple GUIs, ImGUI is a decent option and it is relatively easy to get working. It is a bit non-traditional compared to other frameworks, but it does work and there is a number of complex applications using it.
Alex
 

Offline gmb42

  • Frequent Contributor
  • **
  • Posts: 294
  • Country: gb
Re: How To Incorporate a GUI in C
« Reply #4 on: December 20, 2023, 11:25:13 am »
Somewhat off-topic, for some time Visual Studio has been able to use Clang for compilation, especially with Linux projects.

It's an option in the VS installer.

How well it all works together I don't know.
 

Offline Warhawk

  • Frequent Contributor
  • **
  • Posts: 821
  • Country: 00
    • Personal resume
Re: How To Incorporate a GUI in C
« Reply #5 on: December 20, 2023, 11:30:53 am »
I like the answer that "GUIs always suck" because it is true  :-DD
Not sure if this helps but some weeks ago I had to create a GUI for a reference design. Something that sends commands over CAN from windows-based PC. Python turned out to be quite practical and multi-platform.
I am not sure how complex your GUI is going to be but python can be "quick and dirty". Good luck.

Offline nctnico

  • Super Contributor
  • ***
  • Posts: 26907
  • Country: nl
    • NCT Developments
Re: How To Incorporate a GUI in C
« Reply #6 on: December 20, 2023, 11:47:54 am »
I have a question about C. Being aware of C and having done a few basic programs (i.e. I'm a novice), I asked someone about a very basic compiler that didn't require lots of setting up. He recommended GCC Compiler For Windows which seems to suit my needs well.

Unlike when I tried Visual Studio years ago, I don't need to change several settings and still get compiling issues for programs I know are correct. GCC seems to compile very easy and the few programs I've run compile without needing to wonder if a setting needs to be changed. It has a few drawbacks such as being command line based, having to type the program in Notepad++ , etc... but still, it's decent.

My question is: how can I incorporate a GUI into C?

From reading, I see gtk2-runtime-2.24.10-2012-10-10-ash is something that allows a GUI to be used with GCC, however, I'm not having much luck. I've entered a program the website provided, but get compiling errors.

Also, the reading I've done shows any available GUIs for C are very basic. If so, since GUIs are used in Windows (and Linux), does this mean C++ needs to be incorporated into a C program (as a library?) to have a nicer GUI?
If you want to have your program to have a GUI, look into WxWidgets or QT. Forget about gtk as this is 1) difficult to work with and 2) results in emulated GUI elements which are crappy to use.
You'll need to use C++ with Wxidgets and Qt though but both also provide a lot of other features that take away difficulties when dealing with the OS and offer an easier way to get software written more quickly.
There are small lies, big lies and then there is what is on the screen of your oscilloscope.
 
The following users thanked this post: 5U4GB

Offline T3sl4co1l

  • Super Contributor
  • ***
  • Posts: 21688
  • Country: us
  • Expert, Analog Electronics, PCB Layout, EMC
    • Seven Transistor Labs
Re: How To Incorporate a GUI in C
« Reply #7 on: December 20, 2023, 03:47:12 pm »
I've done, actually, *very* little win32 (or otherwise) GUI programming, directly in C(++)... so don't mind me too much here, but I do have *an* example online just for sake of introduction / discussion:
https://github.com/T3sl4co1l/raycast_win

Just opening a frame and getting a canvas object, setting up menus if applicable, etc., it's not too painful, but there's just a lot of parameters to these objects, and you have to go through EVERYTHING manually, declare all the objects, initialize, register them, write the callback functions, and register them, process notification/message objects... it's a lot of stuff to write out.  Most toolchains/libraries integrate a lot of that boilerplate for you, and many provide a default look and feel, which -- maybe you can take or leave it, but it puts your application into a certain style and feel and you can pick and choose your library in part based on that.

I've done a bit more in Java (which, gosh, that was quite some time ago, now..), which is a bit easier, and kinda maybe a bit more powerful, in that you have the layout managers and stuff handy, if you want to get something more flexible and nicer to use, active resizable etc.  And much of the init and boilerplate is done for you, and the object-oriented nature of Java at least is a strong fit for object-oriented GUIs (which is most of them, AFAIK?).  Of course, it's been decades since Java was "hot", and OOP is just one of many standard language features these days, so, this latter point is pretty unremarkable, buuuut, if you're talking doing it all in C, well, you need to write out all that OOP stuff yourself, and, keeping object-orientation in mind while writing in C can make that a bit easier to understand.

It's ever more complicated as time goes on, for example how desktop styling affects the title bar, frame, etc. (e.g. transparency in Aero (since Vista)), live resizing (I mean that's been around since what, "Plus!"?, but it's up to you how much you want to repaint when it is resized), desktop scaling, accessibility options, etc.  You can use a minimal subset of these, even old (potentially deprecated) APIs, there's a thousand mostly-equivalent ways to do anything you want -- but knowing which ones are best supported/recommended, easiest, and, just which ones are important to provide whatever accessibility / compatibility / etc. features you want to have -- you can read a book or three just to get started on that.  Or go a whole career working with it directly and still be finding new ways of using it.  So, depending on what you want, usability, support, look and feel, and stuff like portability, you may want to choose a library or whatever to handle most of the grunt work.

And yeah, a lot of these tools are available right there in the IDE, using Visual Studio or what have you; it's the go-to environment for this.  The main thing is looking up enough references/docs to make something useful.

Tim
Seven Transistor Labs, LLC
Electronic design, from concept to prototype.
Bringing a project to life?  Send me a message!
 

Offline chilternview

  • Regular Contributor
  • *
  • Posts: 145
  • Country: gb
Re: How To Incorporate a GUI in C
« Reply #8 on: December 20, 2023, 04:57:48 pm »
If you want to lean to create GUIs and use C++ then you could start with the free version of Visual C++. Sure it has a bit of an uphill learning curve at first, but it's not that bad and it has the best debugger around imho.

For GUI development, it really makes sense to use a crossplatform GUI toolkit - added to the fact that Microsoft stuff is truly horrible. Over 20 years ago I tried to use MFC for a gui, after months of tearing my hair out I discovered Qt, doing the same thing took only a few days. Qt has its own IDE, Qt Creator, but I find it slow and irritating to use so do most development work in Windows, with little or no changes to port to Linux/Mac.

 

Offline ejeffrey

  • Super Contributor
  • ***
  • Posts: 3719
  • Country: us
Re: How To Incorporate a GUI in C
« Reply #9 on: December 20, 2023, 05:09:10 pm »
I've done basic GUIs in a few different frameworks in C, C++ and Python, and QT has been the easiest to set things up.  Creating a polished, easy to use and learn GUI is a lot of work for all but the most trivial applications.  But if you just want to throw a bunch of controls on a big canvas, Qt makes it pretty easy.
 

Offline madires

  • Super Contributor
  • ***
  • Posts: 7767
  • Country: de
  • A qualified hobbyist ;)
Re: How To Incorporate a GUI in C
« Reply #10 on: December 20, 2023, 06:33:01 pm »
A good IDE is Eclipse (it's a beast) for example, And for a cross-platform GUI framework I would recommend Qt too. Understanding a GUi framework takes as much effort as learning a new programming language. Often they come with a design tool to make things easier, but it can give you a headache if its output and your program's structure don't match.
 

Online djsb

  • Frequent Contributor
  • **
  • Posts: 893
  • Country: gb
Re: How To Incorporate a GUI in C
« Reply #11 on: December 20, 2023, 06:56:21 pm »
I like BCX (BASIC to C translator) for code prototyping

https://www.bcxbasiccoders.com/

It uses the Windows API directly and works with several C compilers (PellesC (http://www.smorgasbordet.com/pellesc/), etc). It can create GUI and Console based programs.

It has a very helpful forum

https://bcxbasiccoders.com/smf/

HTH.
« Last Edit: December 20, 2023, 07:02:23 pm by djsb »
David
Hertfordshire,UK
University Electronics Technician, London PIC,CCS C,Arduino,Kicad, Altium Designer,LPKF S103,S62 Operator, Electronics instructor. Give a man a fish and you feed him for a day. Teach a man to fish and you feed him for a lifetime. Credited Kicad French to English translator.
 

Offline bostonmanTopic starter

  • Super Contributor
  • ***
  • Posts: 1794
  • Country: us
Re: How To Incorporate a GUI in C
« Reply #12 on: December 20, 2023, 07:13:45 pm »
Guess I'm trying to wrap my head around everything.

From my understanding, C is low level and very powerful meaning one can accomplish more because it's not a language built on top of a language.

Basic C is creating programs that display 'Hello World', perform math, etc... Now we came to an era where we have Windows and a GUI would be useful. Maybe I'm not understanding the feedback or I can't get my head wrapped around this, but does C have its own method of incorporating GUIs or does the only way exist by merging a C program with a IDE that offers a GUI interface?

Deviating a bit, what gets accomplished using C for microprocessors? I know at my old job we had a Software Engineer who ran four PCs and did line-by-line coding that eventually got burned onto EEPROMs. I can only assume the architecture of the EEPROM (or micro) would tell the user specic commands that would read/write and the SE would take those and incorporate them into the code to perform additional calculations eventually spewing results that get fed into other locations.

Is learning C by this method better than takin the initial baby steps of Hello World and/or a GUI based C program?
 

Offline magic

  • Super Contributor
  • ***
  • Posts: 6779
  • Country: pl
Re: How To Incorporate a GUI in C
« Reply #13 on: December 20, 2023, 07:19:24 pm »
C is low level so you will write plenty of code to get anything to show up and then some more for it not to crash within seconds.

Few GUI applications are written in C anymore.

If you want to learn C for purposes where C is actually useful or required (MCUs for instance), forget GUI.
If you want to build a simple GUI application easily, forget C. I have no idea what's used these days, when I was kid VisualBASIC was all the rage ;D
If you want to build a complex GUI application, forget "easily" :P
« Last Edit: December 20, 2023, 07:23:00 pm by magic »
 

Offline bostonmanTopic starter

  • Super Contributor
  • ***
  • Posts: 1794
  • Country: us
Re: How To Incorporate a GUI in C
« Reply #14 on: December 20, 2023, 07:38:12 pm »
Thinking out loud.... I guess maybe I want to learn C because it's powerful, but, at the same time, find the Kernigan and Ritchie approach to learning it to be less than exciting because the C programs don't do much except display results in a text format. It seems as if learning printf and if/then statements are just familiarizing yourself with C and something that is necessary for a school course rather than it being practical to something more useful.

As stated, other (easier) languages exist for achieving similar programs, so I'm really uncertain which area of C is best; I thought a GUI based program would be good but seems it's more trouble than it's worth since GUIs aren't done in C anymore.

Obviously I need much more education in C as I don't understand basic concepts and have more errors in my code than I do correct code, but I find that's the stuff that one improves on as time goes on due to encountering programming errors.

Maybe the question I should ask is whether C is still relevant today? I know this is a loaded question like asking a comic book reader who the best super hero is, but maybe I'm assuming C is still an important language to learn.

On a side note, I also think Assembly (mainly for the Commodore 64) would be cool to know too. I have done some Assembly years ago in college on a little thing that had a keypad and seven segment LCD. We'd enter commands and then it would display the result(s) from a memory location. I don' t remember what those were called, but I'm sure there are GUI based ones now rather than digging out one of those boxes.



 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11262
  • Country: us
    • Personal site
Re: How To Incorporate a GUI in C
« Reply #15 on: December 20, 2023, 07:52:28 pm »
Maybe the question I should ask is whether C is still relevant today?
  It depends. If you are making web sites - no, if you are programming embedded systems - yes.

If you have never programmed GUIs, you will have a lot of issue no matter the language. You just need to pick one and get as far as you can. If you give up at a first error, you will not get anything done with any language.

Qt is a nice framework (be careful with its licensing though). But it is not easy either. It is still easier than doing things from scratch in C or even with Gtk.
Alex
 

Offline shapirus

  • Super Contributor
  • ***
  • Posts: 1361
  • Country: ua
Re: How To Incorporate a GUI in C
« Reply #16 on: December 20, 2023, 09:04:27 pm »
C is a beautiful and powerful language. It is beginner-friendly, as long as you know how to make friends with it. If you can into C, then you can into everything (not without some learning, of course).

I would advise getting comfortable with writing small programs with console (aka command line) interface first.

Start with a simple "write line; read line" approach. Also learn to read from files and write to them.

Then, libreadline.

Then, console window-based libraries, e.g., ncurses, and there were modern more attractive alternatives -- I don't remember the names, maybe someone here does.

Only then, by the time you get comfortable with the language itself, you can expect to be able to approach GUI libraries with success.


What follows is much more of a personal opinion of mine than what I wrote before it.

Ditch Windows. It's not a programmer-friendly OS. Ditch everything that matches the "microsoft" or "visual" keywords. They won't give you the right start.
 

Offline ejeffrey

  • Super Contributor
  • ***
  • Posts: 3719
  • Country: us
Re: How To Incorporate a GUI in C
« Reply #17 on: December 20, 2023, 10:41:09 pm »
Thinking out loud.... I guess maybe I want to learn C because it's powerful, but, at the same time, find the Kernigan and Ritchie approach to learning it to be less than exciting because the C programs don't do much except display results in a text format. It seems as if learning printf and if/then statements are just familiarizing yourself with C and something that is necessary for a school course rather than it being practical to something more useful.

Probably the vast majority of C programs just display output to the console or write to files.  It's so much easier to implement, lets you do the actual job you want to do, and is more easily scripted and automated.  So it's definitely a practical skill.

Quote
From my understanding, C is low level and very powerful meaning one can accomplish more because it's not a language built on top of a language.

It's low level, and that lets you do a lot of things efficiently because the language doesn't do a lot "extra" for you that you might not need or want.  ON the other hand, if you do need those things, you just have to do them yourself.  It is a relatively simple language, which makes it relatively easy to learn, but maybe harder to learn to use it well.

"not a language built on top of a language" doesn't really mean much.  Also, it's not a question of being able to "accomplish more" -- outside of specific low level hardware access which is important in small parts of an OS, you can do all the same things in pretty much any language that hasn't been deliberately sanboxed (like javascript).  C mostly stands out in it's ability (when used properly) to be very efficient, and also that it is basically the lowest common denominator for languages on modern systems.  Pretty much any programming language you choose will be able to support calling external C libraries, because it is so simple and basic.  But Java, C++, and Python support such different object oriented models that it is a lot harder to directly interface between them unless you restrict yourself to a C-like subset of their data models.  C is also the most widely ported language.  That doesn't mean your code is automatically portable, implementations diverge a lot, but you can write C code almost everywhere.


Quote
As stated, other (easier) languages exist for achieving similar programs, so I'm really uncertain which area of C is best; I thought a GUI based program would be good but seems it's more trouble than it's worth since GUIs aren't done in C anymore.

Embedded development is one of the biggest areas of use for C today.  It's used some in high performance computing although C++ is very common.  It's common in basic low-level libraries that need to be accessible from any language.  It's also pretty common in older software projects, especially UNIX based projects started in the early 90s or before) such as the Linux kernel, gcc, CPython. 
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14481
  • Country: fr
Re: How To Incorporate a GUI in C
« Reply #18 on: December 21, 2023, 01:05:29 am »
There's a number (probably very large) of C GUI toolkits out there. GTK is one example that is "mainstream" (outside of the Windows world). If you have already developed GUI programs with basic OS APIs (such as Windows API or macOS, etc), it'll be kinda familiar, but still with a learning curve. I recommend looking at the documentation on the official site: https://www.gtk.org/docs/ . Also, you mentioned a pretty old version of GTK of not clear provenance. It's a recipe for head banging. If you go for GTK, I recommend reading the above docs and using MSYS2 if you're on Windows. It gives you a Linux-like environment that will make it much easier to use GTK (and follow the tutorials and examples): https://www.msys2.org/ . It has a package manager, everything can be installed from there with recent and working versions (dev tools, GTK libs, etc.) Recommended.

If you target Windows only, you could learn the Windows API. It's pretty straightforward, hasn't much changed in over 20 years *for the basic stuff*, and you'll find a ton of material. In pure C.

You also have FLTK, which is a bit dated but worth a shot if you don't know where to start and GTK looks too intimidating: https://www.fltk.org/index.php

Much more out there. Most of course has a learning curve, so don't expect a quick and dirty path to GUIs, but it's all quite usable.
 

Online tellurium

  • Regular Contributor
  • *
  • Posts: 230
  • Country: ua
Re: How To Incorporate a GUI in C
« Reply #19 on: December 29, 2023, 12:23:06 am »
Did anyone mention Web UI?

By incorporating a web server into your C program, you can easily create a Web UI - and a very modern, appealing, sophisticated one.

Or, you could incorporate a headless browser directly into your program, and again - make a web UI! Look at these repos:

https://github.com/webview/webview
https://github.com/webview/lorca

Be cool. Forget about those outdated desktop UI toolkits.
Open source embedded network library https://mongoose.ws
TCP/IP stack + TLS1.3 + HTTP/WebSocket/MQTT in a single file
 
The following users thanked this post: Warhawk

Offline Zipdox

  • Regular Contributor
  • *
  • Posts: 170
  • Country: nl
Re: How To Incorporate a GUI in C
« Reply #20 on: March 07, 2024, 10:32:00 pm »
GTK 3 really isn't that hard.

Here's a quadratic equation solver I wrote. It's quite a few lines but the solver is most of it.
main.c
Code: (c) [Select]
#include <gtk/gtk.h>
#include <math.h>

GtkWidget *a_input;
GtkWidget *b_input;
GtkWidget *c_input;

GtkWidget *d_label;
GtkWidget *x1_label;
GtkWidget *x2_label;

void solve(){
    const char *a_text = gtk_entry_get_text(GTK_ENTRY(a_input));
    const char *b_text = gtk_entry_get_text(GTK_ENTRY(b_input));
    const char *c_text = gtk_entry_get_text(GTK_ENTRY(c_input));

    char *endptr;
    double a = strtod(a_text, &endptr);
    double b = strtod(b_text, &endptr);
    double c = strtod(c_text, &endptr);

    double d, x1, x2;
    char *d_text, *x1_text, *x2_text;

    if(a != 0.0){
        d = pow(b, 2.0) - 4.0 * a * c;

        d_text = g_strdup_printf("d: %f", d);
        gtk_label_set_text(GTK_LABEL(d_label), d_text);
        g_free(d_text);

        if(d >= 0.0){
            if(abs(d) == 0.0){
                x1 = (-b   sqrt(d)) / (2.0 * a);
                x1_text = g_strdup_printf("x: %f", x1);
                gtk_label_set_text(GTK_LABEL(x1_label), x1_text);
                g_free(x1_text);
            }else{
                x1 = (-b   sqrt(d)) / (2.0 * a);
                x2 = (-b - sqrt(d)) / (2.0 * a);
                x1_text = g_strdup_printf("x1: %f", x1);
                x2_text = g_strdup_printf("x2: %f", x2);
                gtk_label_set_text(GTK_LABEL(x1_label), x1_text);
                gtk_label_set_text(GTK_LABEL(x2_label), x2_text);
                g_free(x1_text);
                g_free(x2_text);
            }
        }else{
            gtk_label_set_text(GTK_LABEL(x1_label), "No solution");
            gtk_label_set_text(GTK_LABEL(x2_label), NULL);
        }
    }else{
        gtk_label_set_text(GTK_LABEL(d_label), "No discriminant, it's a inear equation");

        double x1 = -c / b;
        x1_text = g_strdup_printf("x: %f", x1);
        gtk_label_set_text(GTK_LABEL(x1_label), x1_text);
        g_free(x1_text);

        gtk_label_set_text(GTK_LABEL(x2_label), NULL);
    }
}

void button_clicked(GtkButton *button, gpointer user_data){
    solve();
}

void enter_pressed(GtkEntry *button, gpointer user_data){
    solve();
}

int main(int argc, char *argv[]){
    gtk_init (&argc, &argv);
    GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Quadratic Solver");
    gtk_window_set_default_size(GTK_WINDOW(window), 280, 160);
    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);

    GtkWidget *box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);

    GtkWidget *a_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    GtkWidget *a_label = gtk_label_new("a: ");
    a_input = gtk_entry_new();
    g_signal_connect(G_OBJECT(a_input), "activate", G_CALLBACK(enter_pressed), NULL);
    gtk_box_pack_start(GTK_BOX(a_box), a_label, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(a_box), a_input, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(box), a_box, FALSE, FALSE, 0);

    GtkWidget *b_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    GtkWidget *b_label = gtk_label_new("b: ");
    b_input = gtk_entry_new();
    g_signal_connect(G_OBJECT(b_input), "activate", G_CALLBACK(enter_pressed), NULL);
    gtk_box_pack_start(GTK_BOX(b_box), b_label, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(b_box), b_input, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(box), b_box, FALSE, FALSE, 0);

    GtkWidget *c_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    GtkWidget *c_label = gtk_label_new("c: ");
    c_input = gtk_entry_new();
    g_signal_connect(G_OBJECT(c_input), "activate", G_CALLBACK(enter_pressed), NULL);
    gtk_box_pack_start(GTK_BOX(c_box), c_label, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(c_box), c_input, FALSE, FALSE, 0);
    gtk_box_pack_start(GTK_BOX(box), c_box, FALSE, FALSE, 0);

    GtkWidget *solve_button = gtk_button_new_with_label("Solve");
    g_signal_connect(G_OBJECT(solve_button), "clicked", G_CALLBACK(button_clicked), NULL);
    gtk_box_pack_start(GTK_BOX(box), solve_button, FALSE, FALSE, 0);

    d_label = gtk_label_new(NULL);
    gtk_box_pack_start(GTK_BOX(box), d_label, FALSE, FALSE, 0);
    x1_label = gtk_label_new(NULL);
    gtk_box_pack_start(GTK_BOX(box), x1_label, FALSE, FALSE, 0);
    x2_label = gtk_label_new(NULL);
    gtk_box_pack_start(GTK_BOX(box), x2_label, FALSE, FALSE, 0);

    gtk_container_add(GTK_CONTAINER(window), box);

    gtk_widget_show_all(window);

    gtk_main();
}
Makefile
Code: (make) [Select]
CC=gcc
FLAGS=`pkg-config --cflags gtk -3.0`
LIBS=`pkg-config --libs gtk -3.0` -lm

solver: main.c
$(CC) $(FLAGS) -o $@ $^ $(LIBS)

Here's a palindrome checker. Use uses Glade to make designing the UI easier.
main.c
Code: (c) [Select]
#include <gtk/gtk.h>

GtkBuilder *builder;
GtkWidget *window;
GtkEntry *word_input;
GtkWidget *ignore_special_characters;
GtkLabel *result_label;
GtkButton *test_button;

int is_letter_or_number(char character){
    if(character >= '0' && character <= '9') return 1;
    if(character >= 'A' && character <= 'Z') return 1;
    if(character >= 'a' && character <= 'z') return 1;
    return 0;
}

char lowercase(char letter){
    if(letter >= 'A' && letter <= 'Z') return letter   32;
    return letter;
}

int is_palindrome(const char *text, gboolean ignore_special_chars){
    int text_len = strlen(text);

    char *filtered_text = calloc(1, text_len   1);
    int j = 0;
    for(int i = 0; i < text_len; i  ){
        if(ignore_special_chars) if(!is_letter_or_number(text[i])) continue;
        filtered_text[j] = lowercase(text[i]);
        j  ;
    }

    int filtered_text_len = strlen(filtered_text);
    for(int i = 0; i < filtered_text_len; i  ){
        if(filtered_text[i] != filtered_text[filtered_text_len - 1 - i]){
            g_free(filtered_text);
            return 0;
        }
    }
    g_free(filtered_text);
    return 1;
}

void test(){
    const char *input_text = gtk_entry_get_text(word_input);
    gboolean ignore_special_chars = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ignore_special_characters));

    if(is_palindrome(input_text, ignore_special_chars)){
        gtk_label_set_markup(result_label, "<span foreground='#00FF00'>Palindrome!</span>");
    }else
        gtk_label_set_markup(result_label, "<span foreground='#FF0000'>Not a palindrome.</span>");
}

void deleted(){
    gtk_label_set_text(result_label, NULL);
}

int main(){
    gtk_init(NULL, NULL);

    builder = gtk_builder_new_from_file("ui.glade");

    window = GTK_WIDGET(gtk_builder_get_object(builder, "window_main"));
    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);

    ignore_special_characters = GTK_WIDGET(gtk_builder_get_object(builder, "ignore_special_characters"));

    word_input = GTK_ENTRY(gtk_builder_get_object(builder, "word_input"));
    g_signal_connect(G_OBJECT(word_input), "activate", G_CALLBACK(test), NULL);
    g_signal_connect(G_OBJECT(word_input), "backspace", G_CALLBACK(deleted), NULL);
    g_signal_connect(G_OBJECT(word_input), "delete-from-cursor", G_CALLBACK(deleted), NULL);

    result_label = GTK_LABEL(gtk_builder_get_object(builder, "result_label"));

    test_button = GTK_BUTTON(gtk_builder_get_object(builder, "test_button"));
    g_signal_connect(G_OBJECT(test_button), "clicked", G_CALLBACK(test), NULL);

    gtk_widget_show_all(window);

    gtk_main();
}
ui.glade
Code: (xml) [Select]
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.38.2 -->
<interface>
  <requires lib="gtk " version="3.24"/>
  <object class="GtkWindow" id="window_main">
    <property name="can-focus">False</property>
    <property name="title" translatable="yes">Palindrome Test</property>
    <property name="default-width">280</property>
    <child>
      <object class="GtkBox">
        <property name="visible">True</property>
        <property name="can-focus">False</property>
        <property name="orientation">vertical</property>
        <child>
          <object class="GtkEntry" id="word_input">
            <property name="visible">True</property>
            <property name="can-focus">True</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkCheckButton" id="ignore_special_characters">
            <property name="label" translatable="yes">Ignore space and special characters</property>
            <property name="name">ignore_special_characters</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="receives-default">False</property>
            <property name="halign">center</property>
            <property name="margin-start">4</property>
            <property name="margin-end">4</property>
            <property name="margin-top">4</property>
            <property name="margin-bottom">4</property>
            <property name="draw-indicator">True</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">1</property>
          </packing>
        </child>
        <child>
          <object class="GtkButton" id="test_button">
            <property name="label" translatable="yes">Test</property>
            <property name="visible">True</property>
            <property name="can-focus">True</property>
            <property name="receives-default">True</property>
            <property name="margin-start">4</property>
            <property name="margin-end">4</property>
            <property name="margin-top">4</property>
            <property name="margin-bottom">4</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">2</property>
          </packing>
        </child>
        <child>
          <object class="GtkLabel" id="result_label">
            <property name="visible">True</property>
            <property name="can-focus">False</property>
            <property name="margin-start">4</property>
            <property name="margin-end">4</property>
            <property name="margin-top">4</property>
            <property name="margin-bottom">4</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">3</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>
Makefile
Code: (make) [Select]
CC=gcc
FLAGS=`pkg-config --cflags gtk -3.0`
LIBS=`pkg-config --libs gtk -3.0` -lm

palindrome: main.c
$(CC) $(FLAGS) -o $@ $^ $(LIBS)

I suggest you install devhelp and libgtk-3-doc. I use it all the time to check the docs.
« Last Edit: March 09, 2024, 04:25:48 pm by Zipdox »
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4039
  • Country: nz
Re: How To Incorporate a GUI in C
« Reply #21 on: March 07, 2024, 11:02:54 pm »
Did anyone mention Web UI?

By incorporating a web server into your C program, you can easily create a Web UI - and a very modern, appealing, sophisticated one.

Web UIs help to make layout easy, but they are also a pain.

I'd say that overall the easiest environment I've ever used to make UIs and interface them to high performance code is the NextStep / OS X line using Objective C and Interface Builder.

It's like two languages mixed together, with plain C/C++ for the computations, and SmallTalk-like Obj C calls for the UI.  There is a little bit of friction but overall it's I think a lot better than pure C++ stuff like Qt.

I haven't looked at this stuff for over a decade I guess. Is OpenStep / GNUStep practical for making UIs on Linux and Windows? I just looked and their "gorm" Interface Builder clone seems to be under active development still:

https://github.com/gnustep/apps-gorm

There is also open-source Swift. I haven't looked at it, have no idea what the UI story is for it on Linux and Windows. Cool language but it's not C.
« Last Edit: March 07, 2024, 11:23:08 pm by brucehoult »
 

Online mariush

  • Super Contributor
  • ***
  • Posts: 5029
  • Country: ro
  • .
Re: How To Incorporate a GUI in C
« Reply #22 on: March 07, 2024, 11:38:29 pm »
For a more basic library, I'd suggest trying Dear Imgui : https://github.com/ocornut/imgui   wiki page here : https://github.com/ocornut/imgui/wiki

Otherwise... for something native to windows, I'd probably download the source code of a native application and see how the windows are created, menus added and so on.

For example, the first application that comes to mind is VirtualDub, a video editing application : https://virtualdub.sourceforge.net/
 

Offline Zipdox

  • Regular Contributor
  • *
  • Posts: 170
  • Country: nl
Re: How To Incorporate a GUI in C
« Reply #23 on: March 07, 2024, 11:43:45 pm »
For a more basic library, I'd suggest trying Dear Imgui : https://github.com/ocornut/imgui   wiki page here : https://github.com/ocornut/imgui/wiki
Personally I'm not a fan. It's C++, which is more complicated than C. It also doesn't integrate well with the desktop and themes.
 

Offline Psi

  • Super Contributor
  • ***
  • Posts: 9953
  • Country: nz
Re: How To Incorporate a GUI in C
« Reply #24 on: March 07, 2024, 11:50:45 pm »
Making a one-off GUI in C is not that hard.
The hard bit is making a "reconfigurable" GUI. One that is flexible so you can easily add new menus and items and controls later with almost zero effort.

The other hard bit is making a GUI that looks professional.

If it's just a one-off and not going to be maintained/upgraded you can simply load images from flash and sort of 'fake it".  e.g. make it look nice by designed all the menu screen images in photoshop instead of generating them on the fly in code

Basically, making a "good" GUI is like coding a new language but with the added complexity of it needing to look pretty :)
But you don't always need that, sometimes you just need it to be good enough.
« Last Edit: March 07, 2024, 11:56:28 pm by Psi »
Greek letter 'Psi' (not Pounds per Square Inch)
 

Offline brucehoult

  • Super Contributor
  • ***
  • Posts: 4039
  • Country: nz
Re: How To Incorporate a GUI in C
« Reply #25 on: March 08, 2024, 12:03:52 am »
For a more basic library, I'd suggest trying Dear Imgui : https://github.com/ocornut/imgui   wiki page here : https://github.com/ocornut/imgui/wiki

That does actually look quite useful, if you have OpenGL available.

Simple things look easy, and complex things are obviously possible, by the example screenshots.
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6264
  • Country: fi
    • My home page and email address
Re: How To Incorporate a GUI in C
« Reply #26 on: March 08, 2024, 01:29:03 am »
Another cross-platform option in C is Simple DirectMedia Layer, aka SDL2, aka libsdl.  It is more commonly used with games rather than desktop applications, but if you want to do simple interactive stuff, it can be easier than the widget toolkits.  Plenty of guides and tutorials online, too.

I am aware of basically three widget toolkits you can use to create portable applications in C, without also depending on C++ or Tcl or some other programming language:
  • Gtk2 (old), Gtk3 (stable, old docs), and Gtk4 (new)
    Originating from GIMP, is the widget toolkit used in Gnome, Cinnamon, Mint, XFCE, and other desktop environments.  It uses its own look and feel in all operating systems, and is themeable.  There is an XML-based UI tool called Glade, and such UIs can be loaded and associated with functions dynamically at run time.  For Windows installation, see here.
     
  • Enlightenment (EFL; C API)
    Used by the Enlightenment desktop environment and some Samsung devices, including Tizen.
    I do not know if precompiled windows libraries and installers are easily available.
     
  • IUP
    Uses native Windows toolkit on Windows, and Gtk (or Motif/Lesstif) on Linux and macOS (not native on macOS).
I currently use Gtk3 in C, and Qt5 in Python.  Python 3 has Tcl/Tk support (tkinter and tkinter.ttk) as a standard module, "built-in", but I just like Qt better.  (My Python Qt programs can use either PySide2 or PyQt5 bindings, autodetected at runtime.)  However, I only use Linux, and do not have Windows licenses at all to even run in a virtual machine.
Gtk can be used from Python too, via gi, or gobject introspection, but I like Qt better.
IUP looks very interesting, if you want the native look and feel in Windows and Gtk-based desktops in Linux.  (It'll use the Gtk look and feel on macOS.)

Widget toolkits use an event-driven approach, in that you are not in full control of the program flow: you create structures (the UI or its basic framework) and pass the control to the library, which will then call your event handlers when it sees fit.
Object-oriented languages make these and extending the UI widgets easier, which is why there are so few widget toolkits written in C.

For heavy computation, I recommend using separate threads, and passing the tasks and the results between the worker threads and the UI thread via thread-safe first-in-first-out queues.  In C, this typically means pthreads aka POSIX threads.  They are surprisingly easy to use, and in e.g. Gtk, one can use the glib functions to insert events to the main event loop from other threads.  For example, if your worker thread sends one event when it starts processing, and another when it completes, you can use these messages to update the button state, instead of changing the button state only when clicked.  Essentially, you might have a pair of buttons forming a single element, where clicking on the "Do it! Do it!" button locks it down, with the "Cancel" button next to it popping up, and when the calculation completes, the "Do it! Do it!" button pops back up and the "Cancel" button gets grayed out, with the results displayed on-screen.  Each of these (button click, sending a message or triggering the work, work completion message) are all separate named events.

The same approach applies if you create simple static tool pages in HTML+JavaScript, to run in your browser, without requiring any kind of a server or a network connection, as the entire page and Javascript code is included in the HTML file (as source code).  There, you only need to use the window.setTimeout() method to start the "background work" as soon as possible, and not within the event handler, to have it be done in essentially a separate thread.  If you do it in the event handler, it will "freeze" the UI for the duration of your computation/work.   Browsers today have amazingly fast JavaScript interpreters/JIT compilers, so that is a very realistic way to do self-contained graphical tools.  The only limitation is that they cannot load or save files without a network server; you can only present it as text, and optionally copy the text to clipboard to be pasted into other programs.

In Linux, I use a simple Makefile for Gtk projects (that I only need to adjust slightly for each project).  Then, I can run make clean all && ./myprogram to clean the files generated by previous builds, rebuild the program, and run it, whenever I want.  Or, I could even run
    inotifywait -q -e close_write main-file.c -m | while read DUMMY ; do reset ; make || break ; done
to rebuild the code automagically whenever I save main-file.c, regardless of what editor I choose to use.

Adding anything Fourier or DCT-related, I do via the fftw3 library.  The trick with it is "wisdom", or previous knowledge on how a specific-size window is transformed most efficiently.  With pre-discovered wisdom, it is ridiculously efficient and fast even on large FFT window sizes.  It's what toolkits like numpy and scipy tend to use underneath, too.  (With Gtk, it is best to integrate the wisdom to the gtk application properties/settings.)

Integrated Development Environments or IDEs combine an editor, make-like project build management, and often a debugger interface and even a built-in git or other version management software client, in a single user interface.  It is not all a single program, just a single user interface.  Often, the main interface program calls external programs (like the compiler and the debugger) internally, receiving their output via a pipe, and optionally displays these in some window, or just on a status bar as a summary message (success/failure).  Because of the previous paragraph, I personally don't have any use for IDEs right now.

There is even a Gtk extension widget, GtkSourceView (provided as an add-on library to Gtk: 2.10, 3.24, 4.2, other versions, git), that provides a full syntax-highlighted text editor widget all-in-one, with most programming and scripting and mark-up languages' syntax supported out-of-the-box.
« Last Edit: March 08, 2024, 01:31:19 am by Nominal Animal »
 

Offline bostonmanTopic starter

  • Super Contributor
  • ***
  • Posts: 1794
  • Country: us
Re: How To Incorporate a GUI in C
« Reply #27 on: March 08, 2024, 04:08:39 am »
Some substantial feedback has been provided and I'm only elaborating a bit on thoughts.

My problem is that I'm hardware far more than software. From experience, the best programmers I've come across are ones who have done programming for many decades so they have a good foundation. My background is C64 BASIC, some Pascal, a single course in C++ many years ago, and the rest is all seeing code from various languages. For example, I did some Assembly on these little boxes with seven-segment displays (if I remember correctly - but don't remember what they were or the model) way back when I also took Pascal and I've looked at HEX code many times on the C64 (keeping in mind I'm hardware and know binary, HEX, etc...).

So I can look at SOME codes and tell you which language it is. Just recently, long story short, I looked at Assembly Code someone created many years ago for a C64 game. I said to him, looking at the code, it looks like you're loading something into the accumulator, adding this, blah blah. He was impressed I could read the code, however, as I told him, I could only recognize a few lines and know very little.

Having said all this, I'm use to having the software "handed" to me meaning: I never had to incorporate tools or install modules to type/run a program. I'm used to BASIC just being there for me, or (I never did this) but loading a program where I just start typing BASIC lines without the need to install modules.

As I may have mentioned, the little C I've done hasn't provided anything "fun" to visualize. After getting past some of the first chapters in a C book, I found myself bored only getting results of "hello world" or performing some math calculations.

Attached is the type of GUI I think would be interesting to incorporate, but wonder what was used to create it since it runs on Windows. Without a GUI (as stated above) there isn't any visual feedback. The feedback is somewhat repetitive as in: I added two numbers in a C program, compiled, ran, got the answer, now I change the numbers, compile, run, etc...

Most likely things I'd like to create with a GUI are far more advanced such as reading data from a USB, sending data to a device (such as a circuit I built), or whatever, so maybe I'm dreaming a bit too big with the idea of GUIs. In general, I think spitting out the results of code looks far more better in a GUI than a black and white DOS screen. So I think "hello world" displayed in a GUI can open the doors to programming more elaborate programs than living in a DOS world.

 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11653
  • Country: my
  • reassessing directives...
Re: How To Incorporate a GUI in C
« Reply #28 on: March 08, 2024, 05:13:12 pm »
C/C++ is only generic programming language, if you want GUI you need to embed OS's API into the programming, not an easy beginner level. i can only say about Win32 API because thats what i only learnt. if you want down to the metal programming in C/C++ for Windows i suggest old book https://www.amazon.com/Windows-Writing-Reusable-Schulman-Programming/dp/020160891X by Paul Dilascia and i've made a very basic Windows GUI "framework" (classes) with guidance from the book, so i can compile it from raw Ms VC++ 6 the old version. you can PM me if you interested in looking the framework just to see how the basic stuffs work. having doing the exercise i came to the conclusion the appreciation of already existing and most robust and complete framework such as Qt, Borland Windows C++ (now Embarcadero i think) or WxWidgets... i choosed Qt as my next IDE in C/C++ with Windows GUI if anything... but i dont have urgent need since i still can use my old VB6 to develop stuffs. fwiw.
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline shapirus

  • Super Contributor
  • ***
  • Posts: 1361
  • Country: ua
Re: How To Incorporate a GUI in C
« Reply #29 on: March 08, 2024, 05:33:54 pm »
if you want GUI you need to embed OS's API into the programming
...and that's exactly where you lay the foundation of your program being impossible to port to other operating systems at a later time when you need it.

Portability is one of the goals of GUI toolkit libraries such as Qt, GTK and many more. With them you don't need to call OS API functions, you only use the interface of the library, which is (ideally) independent of the operating system.
 

Offline Mechatrommer

  • Super Contributor
  • ***
  • Posts: 11653
  • Country: my
  • reassessing directives...
Re: How To Incorporate a GUI in C
« Reply #30 on: March 08, 2024, 05:59:03 pm »
if you want GUI you need to embed OS's API into the programming
...and that's exactly where you lay the foundation of your program being impossible to port to other operating systems at a later time when you need it.

Portability is one of the goals of GUI toolkit libraries such as Qt, GTK and many more. With them you don't need to call OS API functions, you only use the interface of the library, which is (ideally) independent of the operating system.
i was talking down to the metal programming for exercise and experience feel... more robust cross platform such as Qt will have another classes/macros on top to check on which OS it is operating and divert class path and chain accordingly, underneath are few OSes classes/platform like the basic one i was exercising. the exercise was a good one to get a grasp of how complicated to develop a complete system such as Qt, not a one man job.
Nature: Evolution and the Illusion of Randomness (Stephen L. Talbott): Its now indisputable that... organisms “expertise” contextualizes its genome, and its nonsense to say that these powers are under the control of the genome being contextualized - Barbara McClintock
 

Offline shapirus

  • Super Contributor
  • ***
  • Posts: 1361
  • Country: ua
Re: How To Incorporate a GUI in C
« Reply #31 on: March 08, 2024, 07:24:42 pm »
i was talking down to the metal programming for exercise and experience feel...
Yeah that is definitely a useful practice, which some may find interesting enough to choose as their primary area. But as usual, it's important to choose the right tool for the job. For embedded systems, for developing cross-platform libraries -- yes, you quite rightfully need to interact with the target system on a low level. For developing a generic app which does not need to be closely coupled with a specific platform... then a cross-plaform toolkit is a better way to do it.
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6264
  • Country: fi
    • My home page and email address
Re: How To Incorporate a GUI in C
« Reply #32 on: March 08, 2024, 09:38:55 pm »
After getting past some of the first chapters in a C book, I found myself bored only getting results of "hello world" or performing some math calculations.
This is an universal problem for anyone interested in using programming as a tool to achieve a purpose, instead of learning it for the fun of it.
Getting nice visual and sonic feedback from the code you write is an important way to keep your motivation high.  (With dopamine kicks!)

My recommended solution is not to try and incorporate everything into the C program, simply because I do not do that in the real life either.  Instead, use it for the interesting bits, and pipe the inputs from and outputs to useful sonification or visualization tools.

The main ones I recommend, are
  • Gnuplot.  Program output consists of points, which will be visualized into plots – curves or surfaces – by a simple gnuplot command.  Typically used with math stuff, like approximate functions, comparing your own fixed-point math implementation against the native floating-point implementation, and so on.
     
  • Graphviz.  Program output is DOT language text, describing graphs or directed graphs, including trees and forests.
    This is particularly useful for visualizing nested function exection, and many different types of data structures from heaps, trees, linked lists, to hash tables, disjoint-set data structures, and so on.
     
  • Netpbm tools.  Program output is an image in one of the very easy-to-use formats (PBM/P4 for bitmaps, PGM/P5 for grayscale images, and PPM/P6 for full-color images).  If directed to a file, the output can be opened in Photoshop, GIMP, and many other image editors.  Netpbm is a collection of utilities to convert the images to and from these formats.  For example, if your program modifies an image, you use netpbm tools to convert the input images, losslessly, to the corresponding PBM/PGM/PPM format, then does the pixel manipulation, and outputs the modified image as PBM/PGM/PPM format, which can then be converted to whatever format you like.  To load and save these images correctly, you only need a simple header file implementing a couple of functions; not even a library.  You can also write your own functions easily to do this with the tools you normally use, although they will typically be much less portable.
     
  • SVG 1.1.  This is the file format browsers support for describing vector graphics.  For example, the graphics on my home page is a simple SVG image embedded in the HTML file, all in plain text you can see if you view the page source.  If you save or redirect the output to a file, you can open the generated image in any browser.  I use this to generate vector graphics representations and diagrams, especially using 1:2 isometric perspective for 3D objects.  (The math for that is trivial, and you've seen similar in pixel art games already.)
     
  • aplay -f S32_LE -c1 -r48000 or paplay --format=s32le --channels=1 --rate=48000 to play mono sound at 48000 samples per second, each sample being a int32_t.  This is the easiest way to generate sounds.  If you intend to use low-quality audio reproduction on a microcontroller, you can use -f U8/--format=u8 instead, in which case each sample is an unsigned char, between 0 and 255, corresponding roughly to various PWM and PDM methods to generate an unipolar (0 to Vcc) audio signal.
For interactive stuff, I wholeheartedly recommend starting with Curses (especially ncursesw) for terminal stuff.  ncursesw supports Unicode glyphs, so that when you use a good-coverage font in your terminal, you have much more than the DOS cp437 old-style ANSI graphic characters.  You can also use the ANSI escape sequences to colorize your terminal output, although for unbuffered input you need to do more work.  Yes, this is the "DOS-like" stuff, but it is much simpler than other GUI approaches.

One of my favourite examples is to combine a maze generator and a singleplayer maze game in a Curses application, as a minimal start to old Rogue-like games.  (NetHack ring a bell?)

When using Curses "DOS-like", you still have the full control of the program flow.  When you move to Gtk or other GUI widget toolkits, you must relinguish the full control, and switch to event-driven model.  Essentially, the GUI toolkit will be given full reign of the control flow, and it will simply call some of your functions when necessary.  You cannot do "delay for 50 milliseconds" anymore, you instead must use an interface to say "after 50 milliseconds or more have passed, please call this function, toolkit".  While Gtk is pretty easy to use if you have experience in C, combining learning C and the event-driven model into a single learning step seems a bit risky/harsh/difficult to me.

Unfortunately, all of this is much easier in Linux than in Windows, because you basically have everything you need for these installed in Linux, or can get them installed in with just a few clicks (or a single command-line command starting with sudo apt install or sudo rpm install), as everything is provided in standard software repositories for all Linux distributions.  It helps that everything, even Curses documentation, is available as man pages, so a simple man function or man -k topic will usually provide you with details on what you seek.  I often also have a web browser open at Linux man pages project and whatever library pages or other documentation I use, since memorizing details is wasted effort (and only risks bugs when one remembers the details wrong).

I have not had an opportunity to work with anyone learning game programming via SDL2 (which is C and highly portable, used for the basis of many, many 2D games), but as I mentioned earlier, it is another possibility.  It is somewhat event-driven, too, but with focus on near-realtime and similar, as is needed by typical games.

I used to do some volunteer tutoring/bugfixing for STEM students having Linux laptops, and it was fun to see how fast they progressed from using the default tools to adjusting everything for maximum personal comfort/productivity, and concentrating on getting the task at hand done (learning programming, and using various computational tools from computer algebra to numeric calculation to running distributed simulations on the local HPC clusters).  Many of them were not interested in Linux at all, and only used it as a tool to get things done.  I think that is a very good, very useful attitude.  Linux has no value to me unless I can use it to achieve something interesting or useful to me.

So, my suggestion would be to install some Linux distribution, perhaps Linux Mint, in a virtual machine in your Windows, and do this stuff there.
Or, if you happen to have an old laptop not grunty enough to run Windows anymore, install Linux on that.  (I use a 6+ year old EliteBook 840 G4 with a Core i5 7200U, and it is plenty grunty enough.)

Otherwise, you'll need advice from others who used Windows to learn C programming.  My own experience with such persons is from a decade ago (I havent used Windows in anger for longer than that, even though I used to use and even administer a network of Windows machines over two decades ago), but it was consistently... not positive.  They hadn't learn C per se, they had learned the Microsoft way, and had big trouble learning portable stuff (especially anything POSIX.1, which is absolutely useful), basically because they needed to unlearn Microsoft-specific details and truths they had learned without noticing, having learned to assume them to be axiomatically true everywhere; and now, they had to replace that with new learning.  Unlearning is harder than learning, so it ended up being 2× or more difficult for them.
Those who had more than one OS available, and were used to the idea that a fact in one is not necessarily a fact in the other, even though they are very similar –– just have differences in approach and interface details –– had it much, much easier, because they didn't need to work on the "unlearning" part.
Old C64 and DOS plus Windows gives you already a much better starting point, although mixing in some macOS and perhaps Linux would not hurt.

For best advice, I recommend you listen to someone who uses Windows to write C code for both hosted (Windows or other OS) stuff, and for programming microcontrollers.  Like I said, my observations are dated and negatively colored; someone having done that successfully will be more use to you.

When you get the basics of C down, you'll find it rather straightforward to progress to Gtk+ (or the other widget toolkits, or to SDL) to do GUI stuff, if you want to.  The main step there is relinguishing control of the program flow to the toolkit/library, and the associated change in thinking/code-structuring/design approach.

I often don't go that way, because I prefer doing the user interface in Python –– requires no compilation, lets end users easily tweak UI details without knowing much about programming –– with any heavy computation or trickery or proprietary stuff implemented in a native library, C code compiled to a shared library, that is accessed via the Python ctypes module.  This is quite portable, too, as long as the shared library is compiled for the target architecture and OS.
That said, I have written Gtk+ GUI apps in C for specific useful cases.  There should be a skeletion of a VU meter here somewhere, for example.

For connecting to microcontrollers, I currently use USB Serial, and in Linux, macOS, BSDs the termios interface; not any library.  (I'm particularly unhappy with libserial, libusb, etc.; they seem to work for many, but having taken a careful look at their code, I don't trust them at all.)
This applies to both C code and Python GUI code.  Unfortunately, it is not portable to Windows.

I *often* play with USB HID devices, like keyboards, mice, joysticks, gamepads, etc.  The Linux interface is truly simple, a single one covers all, and if you want, you can easily synthesize one using a simple (privileged) application.  This is why I much prefer microcontroller development boards with native USB interfaces.  My preferred one is USB Serial + USB HID endpoints on the same device.  (There are several 8-bitters from CH552G to ATmega32U4 capable of this.  Teensy 4.x can provide data over USB Serial at 25+ mbytes/sec, or 200 Mbit/s, as it supports USB 2.0 High Speed (480 Mbit/s); most only support Full Speed (12 Mbit/s).)

For bulk and isochronous transfers, I like to use the Linux-specific "usbfs".  It is not a filesystem, just a device interface for the "raw USB device", without any kernel or userspace driver at all.  It is what libusb typically uses under the hood, but in a way I find much less than optimal.

The one key "trick" in Linux is to add an udev rule that permits your user account or group it belongs to, full access to the device.  That way there are no privilege issues.  It is common to forget to do this or skip this as "I'll do it later, as I just want to test this for now", and then complain about all the access- and insufficient privilege-related problems they encounter, and how difficult everything seems to be.
I even use my own wrapper around avrdude, so that when programming my ATmega32u4 (Pro Micro clones off eBay, using the Arduino Leonardo bootloader), the wrapper script resets the target microcontroller, and waits for it to appear, and reprograms the appearing one; regardless of what port/device was selected in the Arduino UI, because that way I avoid the occasional case when the OS changes the microcontroller "USB address" or device node, when the microcontroller is reset/rebooted.
Teensies have their own GUI-based utility which works solidly for me, but there is also a command-line one available at Paul Stoffregen's GitHub.

A few years ago, I mentioned in another thread here that I was thinking of creating a course on how to interface microcontrollers (via USB Serial and USB HID) to a GUI program written in Python for Linux, BSDs, and macOS, but it fell through.  I don't have anything written down, but as it is something I often do, I have lots of ideas on how to do this, starting from manipulating leds and relays on the microcontroller, to transferring intensive amounts of ADC'd data and processing them using FFT or similar (using e.g. fftw3).
« Last Edit: March 08, 2024, 09:44:41 pm by Nominal Animal »
 

Offline Zipdox

  • Regular Contributor
  • *
  • Posts: 170
  • Country: nl
Re: How To Incorporate a GUI in C
« Reply #33 on: March 09, 2024, 04:25:07 pm »
Making a one-off GUI in C is not that hard.
The hard bit is making a "reconfigurable" GUI. One that is flexible so you can easily add new menus and items and controls later with almost zero effort.
Let me introduce you to https://en.wikipedia.org/wiki/Glade_Interface_Designer
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14481
  • Country: fr
Re: How To Incorporate a GUI in C
« Reply #34 on: March 09, 2024, 09:32:17 pm »
After getting past some of the first chapters in a C book, I found myself bored only getting results of "hello world" or performing some math calculations.
This is an universal problem for anyone interested in using programming as a tool to achieve a purpose, instead of learning it for the fun of it.
Getting nice visual and sonic feedback from the code you write is an important way to keep your motivation high.  (With dopamine kicks!)

Yeah, the immediate reward problem I mentioned in another thread. This isn't doing us any good.
Sure some level of reward helps, but do not look for too much initial reward when learning something new, because it is a very sure way of getting bored very quickly.
 

Online Nominal Animal

  • Super Contributor
  • ***
  • Posts: 6264
  • Country: fi
    • My home page and email address
Re: How To Incorporate a GUI in C
« Reply #35 on: March 09, 2024, 10:50:00 pm »
Sure some level of reward helps, but do not look for too much initial reward when learning something new, because it is a very sure way of getting bored very quickly.
True, too.  (The underlying issue is that when you already have a purpose in mind, and getting there takes several steps, you do need some feedback to keep your motivation up.  Otherwise the sucky part of the learning curve can suck more than one can handle.)

You could say my suggestion is more about lowering the amount of programming to get to that feedback in modest amounts, in a way that will be useful in the future too.  Even Curses interfaces are useful on headless appliances and SBCs, when you use a SSH connection to the device.

I at least do not incorporate plotting libraries and whatnot in my C code, because I do all that with less effort using existing effective external command-line tools, that support many use different cases, letting me achieve each task by combining different tools with less throwaway programming.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf