在传统的基于继承的GUI框架中,使用Go语言应该如何访问窗口组件?

huangapple go评论74阅读模式
英文:

Using Go, how should I access window components in traditional inheritance based GUI Frameworks?

问题

我正在使用Go的GTK绑定进行一些实验性工作。

与大多数GUI框架一样,GTK GUI应用程序通常会生成一个主窗口,并在该窗口的上下文中完成应用程序的工作。

当你用C++编写GTK GUI应用程序时,你会继承框架窗口类gtk.Window,并将其他GUI组件声明为继承窗口类的公共成员(或者在窗口类中使用公共访问方法)。这样,它们可以被窗口控制器类操作,该类通过名称将它们作为窗口类的成员进行处理。你只需将主窗口的指针传递给控制器类,并通过编写mWindow.MyWidget.text="text"等代码来操作其成员。据我所知,大多数GUI应用程序都是以类似的方式设计的,无论使用的是哪个GUI框架。

然而,由于Go不支持继承,这种选项是不可能的:当你在Go-Gtk窗口中实例化其他GUI组件时,它们是独立的变量,而不是父窗口类的成员-它们不在容器类中"存在"。这意味着你的GUI控制器类必须单独访问主窗口中的每个组件,没有一个统一的结构或单一的引用可以引用它们。这会影响代码的可读性和良好的代码组织,我认为这迫使你的代码结构不够良好。

我认为在Go中解决这个问题的方法是声明一个结构体/接口,作为主窗口GUI组件的容器。该接口将公开访问组件的方法,并可以传递给GUI控制器单元以操作其成员。

我需要知道是否有一个标准的Go设计模式来处理这样的任务,或者使用Go解决这个问题的正确方法是什么。

我知道Go是为系统编程设计的语言,不是为前端开发而设计的,但我听说过有人说过"每个好的系统语言最终都会被用于应用程序开发",而当今没有比Go更好的系统语言了-证据就是许多用于GUI框架和其他应用程序任务的Go绑定正在出现。不用看得太远,只需看看Go项目列表就知道了。

我想从中得出的结论是,Go并不是为了方便开发桌面GUI应用程序而设计的,而这类应用程序正在逐渐减少。

英文:

I am doing some experimental work using GTK bindings for Go.

As with most GUI frameworks, a GTK GUI app generally spawns a main window and the application's work is done within the context of that window.

When you write a GTK GUI app in C++, you inherit from the framework window class - gtk.Window - and declare the other GUI components for your app as public members of your inherited window class (or use public access methods in your window class). That way they can be manipulated by a window controller class. which addresses them by name as members of your window class. You simply pass a pointer to your main window into the controller class and manipulate its members by writing mWindow.MyWidget.text="text", etc. Again, AFAIK, most GUI applications are designed similarly, regardless of the GUI framework being used.

However, since Go does not support inheritance, this option is not possible: When you instantiate additional GUI components in a Go-Gtk window, they are self standing variables, not members of the parent window class - they don't "live" in a container class. This means that your GUI controller class would have to access each component in the main window individually, with no cohesive structure or single reference to refer to. This compromises readability and good code organization, IMO - forces your code to be somewhat poorly structured.

I believe the solution to this problem in Go would be to declare a struct/interface that will serve as a container for all the main window's GUI components. That interface would publish access methods for the components and could be passed to a GUI controller unit for manipulating its members.

I need to know if there is a standard idiomatic Go design pattern for such a task, or what would be considered the correct approach to this issue using Go.

I understand that Go is designed to be a systems programming language, not really designed with frontEnd development in mind, but I have heard it said that "every good systems language will end up being used for applications", and there is no better systems language out there today than Go - the proof is that many Go bindings for GUI frameworks and other application tasks are surfacing. Look no further than A list of Go projects.

I guess the takeaway from all this is that Go is not designed to make it easy to develop desktop GUI apps, which are a dying breed.

答案1

得分: 2

如果我必须使用Go编写一个带有GUI的应用程序,我会完全将GUI部分与应用程序部分解耦。这种方法的一个示例是GTK Server

不过,你不需要一个单独的进程来处理GUI:你可以在一个goroutine中完成,该goroutine使用通道与应用程序的其余部分进行通信,就像Gtk Server使用套接字/管道/消息队列一样。

我不知道有谁使用过这种方法,我自己只在一个玩具程序中使用过,该程序构建了一个简约的Tk GUI(使用Tk是因为它有一个内置的解释器,当时还不知道gtk-server)。但对我来说,这是使用Go构建GUI应用程序的惯用方式。

英文:

If I had to write an application with a GUI in Go, i would completely decouple the GUI part from the application part. An example of such approach is the GTK Server</a>.

Only, you don't need a separate process to handle the GUI: you can do that in a goroutine, that communicates with the rest of the application using channels, the same way the Gtk Server uses sockets/pipes/message queues.

I don't know of anybody who used this approach, and I used it myself only in a toy program that builds a mimimalistic Tk GUI (used Tk because has a built-in interpreter and didn't know yet of gtk-server). But this would be for me the idiomatic way to build a GUI application in Go.

答案2

得分: 1

你正在询问如何将一组事物分组成一个集合,以便控制器可以访问其中的所有事物。你提到在C++中,可以将这个集合作为gtk.Window的子类。在Go语言中,没有类或类型层次结构,但解决方案类似。

解决方案就是定义一个结构体。可能是这样的:

type MainWindow struct {
    Win         *gtk.Window
    RedButton   *gtk.Widget
    GreenButton *gtk.Widget
}

窗口的控制器可以访问任何字段,无需额外的方法或访问器:

type MainController struct {
    W *MainWindow
    其他字段...
}

func (mc *MainController) DoSomething() {
    mc.W.RedButton.MakeVisible(true)
    mc.W.GreenButton.MakeVisible(false)
}

这里的方法只是为了说明,显然可以根据实际情况进行调整。

英文:

You're asking how one might group a set of things into a collection, such that a controller can access all of them. You note that in C++, one would make this collection a subclass of gtk.Window. In go, there's no classes or type hierarchies, but otherwise the solutions are similar.

The solution is just to define a struct. Perhaps something like this:

type MainWindow struct {
    Win         *gtk.Window
    RedButton   *gtk.Widget
    GreenButton *gtk.Widget
}

A controller for the window can access any of the fields, without additional methods or accessors being needed:

type MainController struct {
    W *MainWindow
    other fields...
}

func (mc *MainController) DoSomething() {
    mc.W.RedButton.MakeVisible(true)
    mc.W.GreenButton.MakeVisible(false)
}

The methods here are just for illustration, obviously.

huangapple
  • 本文由 发表于 2014年4月12日 05:24:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/23022842.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定