Grafische Oberfläche. Aber wie?



  • Hallo Community, ich entwickle unter Windows 10 und cygwin64, jedoch nicht mit dem VisualStudio. Nun bräuchte ich ein GUI für mein bislang noch CLI-Programm, welches Folgendes beinhaltet:

    • "Fenster", schließen, minimieren, maximieren, etc.,
    • Textfeld, für die Ausgabe von Plaintext und die manuelle Änderung von Plaintext,
    • Fortschrittsbalken, die Werte 0 bis 100 sollten anzeigt werden können,
    • 5 Buttons, wenn man einen Button anklickt, dann soll das Programm etwas tun,
    • ein "Programmdesign", das MVC-Pattern wäre wünschenswert, also die Aufteilung in Daten, Oberfläche, Listenern und Logik...

    Lässt sich das irgendwie so leicht wie ein Kinderspiel umsetzen?



  • Naja, eigentlich geht das schon relativ einfach. Ich nutze dafür QT mit QtQuick. Da ist vieles eigentlich Klickibunti, zumindest bei dem was du vor hast.



  • QT finde ich persönlich gut,aber ob das mit CLI kompatibel ist, kann ich dir nicht sagen, weil ich es noch nicht probiert habe. Ich persönlich kenne es nur für python und reines c++.



  • @It0101 sagte in Grafische Oberfläche. Aber wie?:

    QT finde ich persönlich gut,aber ob das mit CLI kompatibel ist, kann ich dir nicht sagen, weil ich es noch nicht probiert habe. Ich persönlich kenne es nur für python und reines c++.

    Mit CLI ist ein consolen programm gemeint (Command Line Interface)



  • @firefly sagte in Grafische Oberfläche. Aber wie?:

    @It0101 sagte in Grafische Oberfläche. Aber wie?:

    QT finde ich persönlich gut,aber ob das mit CLI kompatibel ist, kann ich dir nicht sagen, weil ich es noch nicht probiert habe. Ich persönlich kenne es nur für python und reines c++.

    Mit CLI ist ein consolen programm gemeint (Command Line Interface)

    Achso, die Abkürzung war mir nicht geläufig. Aber ich finde es natürlich auch wichtig, dass man etwas total triviales mit einer knackigen mehrdeutigen Abkürzung versieht. Bei CLI denke ich an .NET-Gedöns.



  • Danke, ich arbeite mich ein in QtQick.

    Mit CLI ist einfach ein C++-Programm gemeint, das bislang nur etwas auf der Konsole ausgibt...



  • @EinNutzer0 sagte in Grafische Oberfläche. Aber wie?:

    Mit CLI ist einfach ein C++-Programm gemeint, das bislang nur etwas auf der Konsole ausgibt...

    CLI heißt/hieß auch die Konsole auf dem Amiga



  • @EinNutzer0 sagte in Grafische Oberfläche. Aber wie?:

    schließen, minimieren, maximieren, etc.,
    Textfeld, für die Ausgabe von Plaintext und die manuelle Änderung von Plaintext,
    Fortschrittsbalken, die Werte 0 bis 100 sollten anzeigt werden können,
    5 Buttons, wenn man einen Button anklickt, dann soll das Programm etwas tun,
    ein "Programmdesign", das MVC-Pattern wäre wünschenswert, also die A

    für winzigen stuff finde ich nana gut.
    http://nanapro.org/en-us/

    Die Library ist nicht tod, sondern noch gut am leben, die Weiterentwicklung ist nur sehr langsam. Und außergewöhnlichen Stuff wird man damit nicht machen.
    Besonders wenn die Anforderungen steigen.
    Aber was gut ist an nana: Es ist für kleine Anforderungen extrem einfach zu nutzen.



  • @It0101 sagte in Grafische Oberfläche. Aber wie?:

    Achso, die Abkürzung war mir nicht geläufig. Aber ich finde es natürlich auch wichtig, dass man etwas total triviales mit einer knackigen mehrdeutigen Abkürzung versieht. Bei CLI denke ich an .NET-Gedöns.

    Nur das Command Line Interface sehr viel älter als .Net Gedöns ist. Beschwer dich also bei MS 🙂 .



  • @5cript
    Bekomme immer folgende Fehlermeldung:

    nana/include/nana/c++defines.hpp:108:2: Fehler: statische Erklärung gescheitert: Only Windows and Linux are supported now (Mac OS and BSD are experimental)
      static_assert(false, "Only Windows and Linux are supported now (Mac OS and BSD are experimental)");
      ^~~~~~~~~~~~~
    

    Könnt ihr mir sagen, was los ist? (Windows, Cygwin, CMake, Make...)



  • Da scheint wohl in c++defines.hpp die Abfrage (in Zeile 83)

    #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)	//Microsoft Windows
    

    nicht zu klappen.

    Evtl. setze einfach in den Projektoptionen eine dieser Makros.



  • Ich hab es jetzt mit GTK versucht.
    Beispiel:

    #include <gtk/gtk.h>
    //...
    static void on_window_closed (GtkWidget *widget, gpointer data)
    {
        gtk_main_quit ();
    }
    //...
        GtkWidget *window, *label;
        /* Initialisieren */
        gtk_init (&argc, &argv);
        /* Fenster erzeugen */
        window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
        /* "destroy"-Ereignis mit einer Funktion verknüpfen */
        g_signal_connect (window, "destroy", G_CALLBACK(on_window_closed), NULL);
        /* Textfeld erzeugen */
        label = gtk_label_new ("Hallo, Welt!");
        /* Textfeld dem Fenster hinzufügen */
        gtk_container_add (GTK_CONTAINER(window), label);
        /* Alle erzeugten Widgets anzeigen lassen */
        gtk_widget_show (label);
        gtk_widget_show (window);
        /* Ereignisschleife */
        gtk_main ();
    //...
    

    compile-Schritt:

    g++ ED.cpp -std=c++11 -lcurl `pkg-config gtk+-3.0 --cflags --libs`
    

    Wenn ich es starte, dann folgende Fehlermeldung:

    Unable to init server: Verbindung mit 127.0.0.1 ist gescheitert: Connection refused
    
    (a:1834): Gtk-WARNING **: cannot open display:
    

    Vielleicht eine etwas blöde Frage, aber was hat X damit zu tun?
    libgtk2.0-dev und libgtk-3-dev sind über Cygwin installiert...



  • @EinNutzer0
    cygwin ist eine POSIX/Unix Umgebung. Da läuft X Windows. Warum benutzt du cygwin?



  • @manni66 sagte in Grafische Oberfläche. Aber wie?:

    @EinNutzer0
    cygwin ist eine POSIX/Unix Umgebung. Da läuft X Windows. Warum benutzt du cygwin?

    Ja warum, warum nicht? Weil ich C++-Programme in Windows ohne das VS entwickeln möchte.

    Geht es vielleicht, wenn ich das "Windows-Subsystem für Linux" installiere:
    Bild 1
    ?



  • @EinNutzer0
    Nein, Sorry, das bringt auch nix.

    Also ich kann es compilieren mit:
    c++ ED.cpp -lcurl -I/usr/include/gtk-3.0 -I/usr/include/pango-1.0 -I/usr/include/glib-2.0 -I/usr/lib/glib-2.0/include -I/usr/include/cairo -I/usr/include/pixman-1 -I/usr/include/freetype2 -I/usr/include/libpng16 -I/usr/include/uuid -I/usr/include/harfbuzz -I/usr/include/gdk-pixbuf-2.0 -I/usr/include/gio-unix-2.0/ -I/usr/include/atk-1.0 -I/usr/include/at-spi2-atk/2.0 -I/usr/include/at-spi-2.0 -I/usr/include/dbus-1.0 -I/usr/lib/dbus-1.0/include -D_REENTRANT -lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 -lintl

    Aber beim Starten kommt eben diese Fehlermeldung, dass er keine Verbindung zu localhost herstellen kann...
    🤬 verfluchtes Windows...



  • @EinNutzer0 sagte in [Grafische Oberfläche. Aber wie?]

    warum nicht?

    Weil du offensichtlich keine Ahnung hast, was du da tust.

    Geht es vielleicht, wenn ich das "Windows-Subsystem für Linux" installiere:

    Du brauchst einen laufenden X Server. Cygwin hat einen. Gegebenenfalls musst du ihn noch Installieren.



  • Ich zeige euch mal, wie das im Visual Studio aussieht (ein Skeleton):

    // WindowsProject1ED.cpp : Definiert den Einstiegspunkt für die Anwendung.
    //
    
    #include "framework.h"
    #include "WindowsProject1ED.h"
    
    #define MAX_LOADSTRING 100
    
    // Globale Variablen:
    HINSTANCE hInst;                                // Aktuelle Instanz
    WCHAR szTitle[MAX_LOADSTRING];                  // Titelleistentext
    WCHAR szWindowClass[MAX_LOADSTRING];            // Der Klassenname des Hauptfensters.
    
    // Vorwärtsdeklarationen der in diesem Codemodul enthaltenen Funktionen:
    ATOM                MyRegisterClass(HINSTANCE hInstance);
    BOOL                InitInstance(HINSTANCE, int);
    LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
    INT_PTR CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
    
    int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
                         _In_opt_ HINSTANCE hPrevInstance,
                         _In_ LPWSTR    lpCmdLine,
                         _In_ int       nCmdShow)
    {
        UNREFERENCED_PARAMETER(hPrevInstance);
        UNREFERENCED_PARAMETER(lpCmdLine);
    
        // TODO: Hier Code einfügen.
    
        // Globale Zeichenfolgen initialisieren
        LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
        LoadStringW(hInstance, IDC_WINDOWSPROJECT1ED, szWindowClass, MAX_LOADSTRING);
        MyRegisterClass(hInstance);
    
        // Anwendungsinitialisierung ausführen:
        if (!InitInstance (hInstance, nCmdShow))
        {
            return FALSE;
        }
    
        HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_WINDOWSPROJECT1ED));
    
        MSG msg;
    
        // Hauptnachrichtenschleife:
        while (GetMessage(&msg, nullptr, 0, 0))
        {
            if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
            {
                TranslateMessage(&msg);
                DispatchMessage(&msg);
            }
        }
    
        return (int) msg.wParam;
    }
    
    
    
    //
    //  FUNKTION: MyRegisterClass()
    //
    //  ZWECK: Registriert die Fensterklasse.
    //
    ATOM MyRegisterClass(HINSTANCE hInstance)
    {
        WNDCLASSEXW wcex;
    
        wcex.cbSize = sizeof(WNDCLASSEX);
    
        wcex.style          = CS_HREDRAW | CS_VREDRAW;
        wcex.lpfnWndProc    = WndProc;
        wcex.cbClsExtra     = 0;
        wcex.cbWndExtra     = 0;
        wcex.hInstance      = hInstance;
        wcex.hIcon          = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WINDOWSPROJECT1ED));
        wcex.hCursor        = LoadCursor(nullptr, IDC_ARROW);
        wcex.hbrBackground  = (HBRUSH)(COLOR_WINDOW+1);
        wcex.lpszMenuName   = MAKEINTRESOURCEW(IDC_WINDOWSPROJECT1ED);
        wcex.lpszClassName  = szWindowClass;
        wcex.hIconSm        = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
    
        return RegisterClassExW(&wcex);
    }
    
    //
    //   FUNKTION: InitInstance(HINSTANCE, int)
    //
    //   ZWECK: Speichert das Instanzenhandle und erstellt das Hauptfenster.
    //
    //   KOMMENTARE:
    //
    //        In dieser Funktion wird das Instanzenhandle in einer globalen Variablen gespeichert, und das
    //        Hauptprogrammfenster wird erstellt und angezeigt.
    //
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
       hInst = hInstance; // Instanzenhandle in der globalen Variablen speichern
    
       HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
          CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
    
       if (!hWnd)
       {
          return FALSE;
       }
    
       ShowWindow(hWnd, nCmdShow);
       UpdateWindow(hWnd);
    
       return TRUE;
    }
    
    //
    //  FUNKTION: WndProc(HWND, UINT, WPARAM, LPARAM)
    //
    //  ZWECK: Verarbeitet Meldungen für das Hauptfenster.
    //
    //  WM_COMMAND  - Verarbeiten des Anwendungsmenüs
    //  WM_PAINT    - Darstellen des Hauptfensters
    //  WM_DESTROY  - Ausgeben einer Beendenmeldung und zurückkehren
    //
    //
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch (message)
        {
        case WM_COMMAND:
            {
                int wmId = LOWORD(wParam);
                // Menüauswahl analysieren:
                switch (wmId)
                {
                case IDM_ABOUT:
                    DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
                    break;
                case IDM_EXIT:
                    DestroyWindow(hWnd);
                    break;
                default:
                    return DefWindowProc(hWnd, message, wParam, lParam);
                }
            }
            break;
        case WM_PAINT:
            {
                PAINTSTRUCT ps;
                HDC hdc = BeginPaint(hWnd, &ps);
                // TODO: Zeichencode, der hdc verwendet, hier einfügen...
                EndPaint(hWnd, &ps);
            }
            break;
        case WM_DESTROY:
            PostQuitMessage(0);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        return 0;
    }
    
    // Meldungshandler für Infofeld.
    INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
    {
        UNREFERENCED_PARAMETER(lParam);
        switch (message)
        {
        case WM_INITDIALOG:
            return (INT_PTR)TRUE;
    
        case WM_COMMAND:
            if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
            {
                EndDialog(hDlg, LOWORD(wParam));
                return (INT_PTR)TRUE;
            }
            break;
        }
        return (INT_PTR)FALSE;
    }
    

    Ich brauche n halbes Jahr, um das zu verstehen...
    Ich wette, das ist absichtlich so kompliziert, damit die Leute nach C# switchen.


    @manni66 sagte in Grafische Oberfläche. Aber wie?:

    Du brauchst einen laufenden X Server. Cygwin hat einen. Gegebenenfalls musst du ihn noch Installieren.

    Danke, tu ich. Ich meld mich gleich nochmal.



  • nimm msys2 statt cygwin für Entwicklung mit g++ auf windows.
    Da hast du ein Package Manager für diverse libraries, cmake, etc.

    https://www.msys2.org/

    Ich benutz das seit Jahren und schaue nicht zurück.

    Wenn du fragen zu msys2 hast such mich im C++ Discord, dann kann ich dir da direkt helfen per PM.



  • Es funktioniert. 🙂

    Hier ist eine Anleitung: https://x.cygwin.com/docs/ug/setup.html

    Aber der cygwin64 folder ist jetzt über 14gb mit über 350.000 files...

    So sieht es aus
    https://a.uguu.se/ppU0ECLXwR2L_22.png

    Aber... dann ist es eigentlich einfacher und konfortabler, in einer VM zu entwickeln... Oder?



  • @5cript Danke, werde ich mal ins Auge fassen... 🙂


Log in to reply