“独立”GUI窗口启动

时间:2010-07-08 14:48:30

标签: user-interface language-agnostic design-patterns d

我是GUI编程的新手,我正在尝试在D中编写一个绘图库,以便与一些基于控制台的科学应用程序一起使用。我正在使用DFL作为我的GUI库。

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

我仍然试图围绕GUI库如何在幕后工作。看起来你应该只有一个GUI线程和一个主要形式。除了语言/特定于库的设计模式之外,我还会欣赏语言/库不可知设计模式的答案。

编辑:要强调的是,除了它在执行中的有趣点上引发的图之外,这个应用程序没有GUI。它基本上是一个控制台应用程序加上一些图表。因此,没有明确定义的“主要”形式。

2 个答案:

答案 0 :(得分:2)

你能做什么可能会依赖于DFL的工作方式。通常,在GUI应用程序中,有一个事件线程可以处理应用程序中的所有事件 - 无论是重新绘制事件,按钮单击事件,鼠标单击事件还是其他任何事件。该线程调用已注册的事件处理程序来处理事件(通常是被点击的小部件或诸如此类的东西)。您遇到的问题是,如果您尝试在这些事件处理程序中执行过多操作,则会锁定事件线程,因此不会及时处理其他事件(包括重绘事件)。一些GUI工具包甚至特别限制了您在事件处理程序中允许执行的操作。有些还将某些类型的操作限制到该特定线程(比如做任何事情 - 尤其是对象创建 - 使用实际的GUI代码,例如工具箱必须具有的各种小部件或窗口类)。

通常,处理此问题的方法是让事件线程触发事件处理程序中的单独线程并让其他线程实际处理事件,或者在事件处理程序中设置一些状态,一个单独的,已经运行的线程会被警告这种状态更改(可能使用观察者模式),并且它会根据该状态适当地处理事情。在任何一种情况下,事件处理程序本身所做的事情通常都相当有限。

GUI的工作方式通常基于事件。该程序处理来自用户和系统的事件,并且在没有发出信号的情况下不会做很多事情。通常,GUI应用程序在事件被告知之前不会执行任何(尽管有很多情况下后台线程正在执行与事件分开的某种工作)。你想要做的事情听起来并不特别基于事件,所以这会让事情变得复杂。

我的猜测是,每次你想要抛出新的情节时,你需要让你的应用程序创建一个新窗口。该窗口可能是主窗口的子窗口,因为您显然不需要它,所以可能会隐藏,并且可能DFL要求您拥有某种类型的主窗口。想要创建一个窗口的每个线程必须告诉主GUI窗口才能做到这一点,但这有很大的机会,但它确实依赖于DFL。 DFL也可以允许任何线程创建新的GUI元素(例如新窗口)。

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

至于线程阻塞,它可能必须忙于等待,直到事件线程收到窗口关闭事件,并且某些共享变量被更新,或者你可以让它进入睡眠直到事件线程醒来收到窗口关闭事件后它。在你不想阻止它的情况下,它只是不在乎等待被告知窗口关闭的事件并且会继续徘徊。

无论如何,希望有足够的信息让你朝着正确的方向前进。通常事件驱动一切,所有内容都悬挂在GUI上,可以这么说。但在您的情况下,您的应用程序更像是stdout使用GUI。所以,你可能最好先做一些小的,相当愚蠢的GUI应用程序,这些应用程序是实际的,正常的,基于事件的GUI应用程序(如Tic-Tac-Toe游戏之类的东西),以便更好地处理在尝试以类似于标准的方式使其工作之前,GUI的工作是有效的。

答案 1 :(得分:0)

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

当应用程序代码包含一些长时间运行的进程时,通常会使用线程,这些进程不能被中断为较小的块(大型计算,复制文件,控制世界......)。然后使用一个线程来保持GUI的响应,而工作则在一个单独的线程中完成。主要问题是保持两个线程同步正确,因为大多数GUI工具包不能处理来自多个线程的调用。当你只有很小的工作部件时,它们不能长时间阻止GUI(<0.1s),那么最好不要使用工作线程。

我还强烈建议将GUI代码和应用程​​序逻辑分开。将GUI代码和应用程​​序代码混合在一起是一个维护的噩梦。