User interface &引用;“独立”;GUI窗口启动

User interface &引用;“独立”;GUI窗口启动,user-interface,language-agnostic,design-patterns,d,User Interface,Language Agnostic,Design Patterns,D,我对GUI编程相当陌生,我正在尝试用D编写一个绘图库,用于一些基于控制台的科学应用程序。我正在使用DFL作为我的GUI库 假设我的绘图表单有一个名为showPlot()的方法,它应该在屏幕上显示绘图。我希望我的应用程序中的任何线程都能弹出一个绘图窗口,阻止绘图,直到绘图关闭,或者继续工作,而showPlot()的调用方不必知道任何其他线程在绘图方面做了什么,或者过去创建了哪些绘图,并且可能仍在屏幕上。(当然,showPlot()的内部可能具备这些知识。) 我仍在试图了解GUI LIB通常是如何在

我对GUI编程相当陌生,我正在尝试用D编写一个绘图库,用于一些基于控制台的科学应用程序。我正在使用DFL作为我的GUI库

假设我的绘图表单有一个名为
showPlot()
的方法,它应该在屏幕上显示绘图。我希望我的应用程序中的任何线程都能弹出一个绘图窗口,阻止绘图,直到绘图关闭,或者继续工作,而
showPlot()
的调用方不必知道任何其他线程在绘图方面做了什么,或者过去创建了哪些绘图,并且可能仍在屏幕上。(当然,
showPlot()
的内部可能具备这些知识。)

我仍在试图了解GUI LIB通常是如何在后台工作的。看起来您应该只有一个GUI线程和一个主窗体。除了语言/库特定的设计模式之外,我还希望在语言/库不可知的设计模式级别得到答案


编辑:要强调的是,这个应用程序除了在执行过程中有趣的地方抛出的图之外,没有GUI。它基本上是一个控制台应用程序加上一些情节。因此,没有定义良好的“主”窗体。

GUI框架通常有自己的事件循环,并将应用程序代码作为对外部事件(按钮单击、计时器、重画等)的回调调用。“典型”控制台应用程序和GUI应用程序之间的主要区别在于,您放弃了对何时向GUI框架调用函数的控制


当应用程序代码包含一些长时间运行的进程时,通常会使用线程,这些进程不能被中断为较小的块(大型计算、复制文件、控制世界等等)。然后使用一个线程来保持GUI的响应性,而工作是在一个单独的线程中完成的。主要的问题是保持两个线程同步,因为大多数GUI工具包无法处理来自多个线程的调用。当您只有小的工作部件时,它不会长时间阻塞GUI(您将能够做什么可能取决于DFL的工作方式。通常,在GUI应用程序中,有一个事件线程处理应用程序中的所有事件-无论是重新绘制事件、按钮单击事件、鼠标单击事件还是其他事件。该线程调用已注册以处理事件的事件处理程序(通常是被点击的小部件或诸如此类的东西)。您遇到的问题是,如果您尝试在这些事件处理程序中执行太多操作,就会锁定事件线程,因此其他事件(包括重新绘制事件)也会被锁定不要及时得到处理。一些GUI工具包甚至特别限制允许您在事件处理程序中执行的操作。一些还将特定类型的操作限制在特定线程中(例如使用实际GUI代码(如工具包绑定的各种小部件或窗口类)执行任何操作,尤其是对象创建)

通常,处理此问题的方法是让事件线程在事件处理程序中触发单独的线程,并让其他线程实际处理事件,或者在事件处理程序中设置一定数量的状态,一个单独的、已经运行的线程将收到此状态更改的警报(可能使用观察者模式)在这两种情况下,事件处理程序本身所做的通常是相当有限的

GUI的工作方式通常是基于事件的。该程序处理来自用户和系统的事件,并且在没有得到通知的情况下不会做很多事情。通常情况下,GUI应用程序在被事件告知之前不会做任何事情(虽然在很多情况下,后台线程都是独立于事件执行某种工作的)。您尝试执行的操作听起来并不特别基于事件,因此这会使事情变得有点复杂

我的猜测是,每当你想要创建一个新的绘图时,你需要让你的应用程序创建一个新窗口。该窗口可能是主窗口的子窗口,该窗口将被隐藏,因为你显然不需要它,而DFL可能要求你拥有某种主窗口。每个窗口都有一个不需要的好机会想要创建窗口的线程必须告诉主GUI窗口这样做,但这实际上取决于DFL。DFL也可能允许任何线程创建新的GUI元素(例如新窗口)

无论如何,它几乎肯定是实际处理窗口的主事件线程。想要创建窗口并填充它的线程可能必须创建窗口(直接或间接),然后通过更新一组共享变量来更新窗口的状态,以便事件线程可以适当地重新绘制窗口。原始线程最有可能实际重新绘制窗口的操作是在更新共享变量的状态后向窗口发送重新绘制事件,这些共享变量包含绘制所需的数据它不能处理这幅画本身

至于线程阻塞,它可能不得不忙着等待,直到事件线程接收到窗口关闭事件,并且某个共享变量被更新,或者您可以让它进入睡眠状态,直到事件线程在接收到窗口关闭事件后将其唤醒。如果您不想让它阻塞,它就不在乎了等着别人告诉我关窗事件的消息,然后继续往前走

在任何情况下,希望这足够的信息让你走上正确的方向。通常情况下,事件驱动一切,可以说一切都挂在GUI上。但在你的情况下,你的应用程序使用GUI更像是stdout。因此,你最好先开发一些小的、相当愚蠢的GUI应用程序,它们是真实的、正常的、基于事件的GUI应用程序(如Tic-Tac-Toe游戏或