Heim >Backend-Entwicklung >Golang >Können Sie ein GTK4-Anwendungsfenster aus einer UI-Datei zu einer GTK4-Anwendung hinzufügen?

Können Sie ein GTK4-Anwendungsfenster aus einer UI-Datei zu einer GTK4-Anwendung hinzufügen?

WBOY
WBOYnach vorne
2024-02-09 19:24:10721Durchsuche

您可以将 GTK4 applicationWindow 从 ui 文件添加到 GTK4 应用程序吗?

PHP-Editor Zimo beantwortet gerne eine häufig gestellte Frage: „Können Sie ein GTK4-Anwendungsfenster aus einer UI-Datei zu einer GTK4-Anwendung hinzufügen?“ In GTK4 können Sie GtkBuilder verwenden, um die UI-Datei zu laden und das darin enthaltene applicationWindow-Widget zu Ihrer GTK-Anwendung hinzuzufügen. Auf diese Weise können Sie die Anwendungsschnittstelle bequemer entwerfen und verwalten und die Entwicklungseffizienz verbessern. Bitte beachten Sie jedoch, dass Sie zum erfolgreichen Laden der UI-Dateien sicherstellen müssen, dass die relevanten Bibliotheken und Tools für GTK4 auf Ihrem System installiert sind. Ich hoffe, diese Antwort hilft Ihnen!

Frageninhalt

Ich verwende GTK erst seit ein paar Tagen, da mein Go-Programm eine GUI benötigt, daher ist dies eine Frage für Anfänger. Als Neuling habe ich den einfachsten Weg gewählt, den ich finden konnte, um mit Cambalache zu beginnen, indem ich eine .UI-Datei generierte und sie dann in meiner Go-App aufrief.

Ich habe alles unter ApplicationWindow in der .UI-Datei abgelegt und lasse es laden und mit gkt4-builder-tool einwandfrei funktionieren, aber in meiner Go-App habe ich keine Ereignisse in der GUI. Als ich mir den Beispielcode ansah, stellte ich fest, dass ich das ApplicationWindow an die in meinem Go-Programm instanziierte GTK-Anwendung anhängen musste, und ich änderte das >ApplicationWindow in nur ein Fenster und es funktionierte gut, weil ich ein normales Fenster hinzufügen konnte zu einer GTK-Anwendung.

Das Problem ist, dass ich keine Möglichkeit finde, das ApplicationWindow aus der UI-Datei zu extrahieren und es dann an die Anwendung anzuhängen. Die einzige Möglichkeit, ein Fenster an eine Anwendung anzuhängen, ist app.AddWindow(), aber es fügt nur ein GtkWindow hinzu, kein GtkApplicationWindow, und in einer stark typisierten Sprache wie go heißt es „no go“ (kein Wortspiel beabsichtigt) .

Sie können eine GTK-Anwendung mit einem ApplicationWindow direkt in eine .UI-Datei exportieren. Wenn Ihnen dies gelingt, könnten Sie theoretisch beide extrahieren und sie möglicherweise auf diese Weise verketten. Ich habe das jedoch nicht erfolgreich exportiert GTK-Anwendung, ApplicationWindow und Menü, weil das gkt4-builder-tool immer wieder Validierungsfehler erhält (nach dem Ausprobieren mehrerer Konfigurationen), sodass Cambalache nicht weiß, wie diese Kombination exportiert werden soll; um dies zu tun; oder wenn es sich tatsächlich nicht um eine zulässige Kombination in der .UI-Datei handelt.

Meine Frage ist also: Sollte ich aufgeben, das ApplicationWindow in der .UI-Datei zu speichern, und einfach das ApplicationWindow-Widget im Code erstellen, oder gibt es eine andere Option? Noch nicht gelernt?

Wenn es nicht wirklich notwendig ist, könnte ich ApplicationWindow weglassen und Windows als anderen Pfad verwenden.

Vielen Dank für Ihr Wissen und Ihre Erfahrung.

Danke!

Update:

Klarer basierend auf den Kommentaren von Kripto.

Hier ist der Code. Dies wird nicht direkt ausgeführt, da ich das relevante Snippet in main() aus einem größeren Programm extrahiert habe und env, log := boot.Initialize() in diesem Snippet nicht vorhanden ist, aber es ist nicht wichtig, das Problem zu verstehen.

Ich weiß, dass es in der GTK-GUI nur ein Anwendungsfenster gibt. Das Konzept ähnelt, wenn nicht sogar identisch, dem Anwendungsfenster aus meiner alten Visual Basic-Zeit.

Hier ist der go-Code und eine komprimierte Version mit den relevanten Elementen aus der .UI-Datei:

Wenn ich Zeile 8 in der Datei .UI ändere:

30d13d358b30f254a61132730e629276

Dazu:

c1b6b103a658abde6319355edf92688c

Der

Go-Code öffnet die Datei .UI und es funktioniert, aber jetzt habe ich kein Anwendungsfenster.

Wenn ich Zeile 8 in der Datei .UI unverändert lasse, wird die Datei trotzdem geöffnet, aber die resultierende GUI ist nicht interaktiv und wird nur geschlossen, wenn ich mein laufendes Go-Programm in Im Debug-Modus in GoLand ausführen stoppe . Dies liegt daran, dass ich zum Ausführen zwei Änderungen am Go-Programm vornehmen musste. :

  1. Ändern Sie diese Zeile:

appWindow := builder.GetObject(appWin).Cast().(*gtk.Window)

zu

appWindow := builder.GetObject(appWin).Cast().(*gtk.ApplicationWindow)

  1. Kommentieren Sie diese Zeile:

app.AddWindow(appWindow)

Das zweite Problem ist, dass das Fenster jetzt nicht mit der Anwendung verbunden ist und ich bin mir sicher, dass es deshalb nicht interaktiv ist.

package main

import (
    "os"

    "github.com/diamondburned/gotk4/pkg/gio/v2"
    "github.com/diamondburned/gotk4/pkg/gtk/v4"

    "gitlab.com/trading5124936/core.git/loggers"
)

func main() {
    env, log := boot.Initialize()
    var app *gtk.Application
    app = gtk.NewApplication(`site.TradingAnalyzer`, gio.ApplicationFlagsNone)
    app.ConnectActivate(func() { activate(app, log, env.Paths.GUIFile) })

    if code := app.Run(os.Args); code > 0 {
        os.Exit(code)
    }

}

func activate(app *gtk.Application, log *loggers.Logger, guiPath string) {
    // You can build UIs using Cambalache (https://flathub.org/apps/details/ar.xjuan.Cambalache)

    b, err := os.ReadFile(guiPath)
    if err != nil {
        log.Critical(err)
        return
    }
    uiXML := string(b)

    builder := gtk.NewBuilderFromString(uiXML, len(uiXML))

    // MainWindow and Button are object IDs from the UI file
    appWindow := builder.GetObject(`appWin`).Cast().(*gtk.Window)

    entry := builder.GetObject(`GeneralSetup.Timezone`).Cast().(*gtk.Entry)
    entry.Connect("changed", func() {
        println(`Changed`)
    })

    app.AddWindow(appWindow)
    appWindow.Show()

}

Dies ist die .UI-Datei:

<?xml version='1.0' encoding='UTF-8'?>
<!-- Created with Cambalache 0.16.0 -->
<interface domain="ta.site">
  <!-- interface-name TradingAnalyzer.ui -->
  <!-- interface-authors Reg Proctor -->
  <requires lib="gtk" version="4.6"/>
  <object class="GtkApplication" id="app"/>
  <object class="GtkApplicationWindow" id="appWin">
    <property name="default-height">925</property>
    <property name="default-width">1200</property>
    <child>
      <object class="GtkPaned">
        <child>
          <object class="GtkFrame">
            <property name="label">Settings</property>
            <child>
              <object class="GtkStackSidebar">
                <property name="halign">start</property>
                <property name="height-request">900</property>
                <property name="stack">pages</property>
                <property name="valign">start</property>
              </object>
            </child>
          </object>
        </child>
        <child>
          <object class="GtkFrame">
            <child>
              <object class="GtkStack" id="pages">
                <property name="name">Timezone</property>
                <child>
                  <object class="GtkStackPage" id="GeneralSetup">
                    <property name="child">
                      <object class="GtkFlowBox">
                        <property name="margin-bottom">20</property>
                        <property name="margin-end">50</property>
                        <property name="margin-start">50</property>
                        <property name="margin-top">20</property>
                        <property name="name">Timezone</property>
                        <child>
                          <object class="GtkEntry" id="GeneralSetup.Timezone">
                            <property name="activates-default">True</property>
                            <property name="halign">start</property>
                            <property name="height-request">10</property>
                            <property name="input-purpose">alpha</property>
                            <property name="placeholder-text">Timezone</property>
                            <property name="text">America/Phoenix</property>
                            <property name="tooltip-text">Enter your timezone</property>
                            <property name="valign">center</property>
                            <property name="width-request">50</property>
                          </object>
                        </child>
                      </object>
                    </property>
                    <property name="name">General Setup</property>
                    <property name="title">General Setup</property>
                  </object>
                </child>
              </object>
            </child>
          </object>
        </child>
      </object>
    </child>
  </object>
</interface>

Update 2

我找到了部分答案。您可以做到这一点,但您需要将 App 添加到 ApplicationWindow 中,而不是相反,因此这是一个不同的功能。这是它的工作方式(它也有点短,因为我了解到有一个从文件加载的函数):

func activate(app *gtk.Application, log *loggers.Logger, guiPath string, appName string) {

    const ext = `.ui`

    guiPath += `/`
    builder := gtk.NewBuilderFromFile(guiPath + appName + ext)
    // builder := gtk.NewBuilderFromFile(guiPath + `Another template File.ui`)

    appWindow := builder.GetObject(`appWin`).Cast().(*gtk.ApplicationWindow)

    entry := builder.GetObject(`GeneralSetup.Timezone`).Cast().(*gtk.Entry)
    entry.Connect("changed", func() {
        println(`Changed`)
    })

    // ***** THE LINE THAT MAKES THE DIFFERENCE ***
    appWindow.SetApplication(app)
    appWindow.Show()

}

我仍然不确定是否存在将应用程序对象导出到这些 .UI 文件之一的情况。

我还没有找到任何人这样做的例子,我倾向于相信这不是你应该做的,但我仍在学习,所以很容易出错。

解决方法

更新 2 提供了此问题的大部分答案。

此外,到目前为止,我认为没有任何理由将应用程序添加到 UI 文件中。无论如何,它往往会抛出错误。

Das obige ist der detaillierte Inhalt vonKönnen Sie ein GTK4-Anwendungsfenster aus einer UI-Datei zu einer GTK4-Anwendung hinzufügen?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:stackoverflow.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen