使用Qt的GUI编程中是否有单身人士? [英] Are Singletons EVIL in GUI Programming with Qt?

查看:105
本文介绍了使用Qt的GUI编程中是否有单身人士?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始了我的第一个相当大的Qt项目,这个项目主要是一大堆按钮,Tab小部件和Qwt Plots的屏幕。 Qt Quarterly 27 中描述的面板堆栈模式对我的应用程序来说似乎很不错。我的每个屏幕都是封装在面板中的QWidget,由QStackedWidget显示/隐藏。然而,它为每个面板使用单例模式,以便在应用程序启动时不会立即创建,因此每个屏幕中都不会创建多个。



所以我开始编码。面板堆栈工作。添加了一些代码,以便动态更新小部件不会一直动态更新。得到我的历史堆栈/返回按钮为面板工作。一切似乎都很好,但我有一个/叨的担心:


  1. 我的代码闻起来。



    1. 我没有任何地方可以与任何在这里发布的仇恨和关于单身人士模式的博客进行争论。我想我得到它,我写的代码确实让我感觉到所有的样板线和全局对象有点脏。但是我不用担心在切换到它之前是否已经实例化了一个屏幕,并将其添加到我的历史堆栈中。我只是说切换到该屏幕,它被添加到我的历史堆栈,并且魔术工作。



      从我读过的还有一些情况下,单身人士可以值得的。这是这些特殊情况之一吗?魔术屏幕切换/历史堆栈让我认为是,但是我将要创建的不同单身人数的绝对数量让我想起不,不,不,不。



      我想只是想起来,弄清楚如何从我的代码现在中获取单例模式,以便我以后不需要这样做。但是我不想摆脱我所有的单身班,只是为了摆脱我的单身班,因为他们是需要引用的。



      任何输入都是非常感谢!

      解决方案

      我真的不讨厌单身人士,但这听起来像是没有用的情况。我不明白为什么在那篇文章中有这么多的单身人士。



      首先,PanelStack本身就是单身人士。为什么?如果这是您的主要小部件,那么只需在main()中的堆栈中创建它即可,它既干净又快捷。如果它是更复杂的UI的一部分,那么将其作为该UI的成员。一个普通的班级在这里很好,单身只限制其可能的用途。



      然后,每个小组也是单身人士?在这一点上,即使是单身恋人也应该开始觉得已经有太多的人了。这可能是为什么你首先提出这个问题。让我们看看单身人士在这里给予什么真正的好处。那么关于我能从这篇文章中得出的唯一的好处就是能够在需要的时候懒洋洋地创建面板。这实际上是一件好事,但事实上,懒惰的创作和单身作品是不同的模式,尽管人们经常使用另一种模式。



      为什么不把所有这些面板放在一些普通容器呢?在这种情况下,PanelStack看起来是一个完美的候选人。毕竟这是面板存放的地方。而不是一堆单例,我们在PanelStack中创建一堆方法:

        class PanelStack:public QWidget 
      {
      Q_OBJECT

      public:
      int addPanel(AbstractPanel *);
      void showPanel(int);
      RecordingsPanel * getRecordingsPanel();
      ReecrdingDetailsPanel * getRecordingDetailsPanel();

      私人:
      ...
      };

      等等。这些 get * Panel()方法仍然可以根据需要懒洋洋地创建面板。现在,它与基本上是一样的单身人士一样,增加了一些优点:




      • 如果我们让堆栈的小孩,当堆栈被删除时,它们被自动删除。没有必要担心内存管理,这总是一个单身人士的痛苦。

      • 您甚至可以在PanelStack中实现某种垃圾收集器,它将删除未用于有一段时间或者当达到某种最大活动面板限制时。



      现在,我唯一可以想到的缺点是我们有现在堆栈和面板之间的依赖关系。但更糟糕的是,将实例存储在一个类中,引入依赖关系,还是在全局存储?如果您认为堆栈应该独立于面板,这听起来很合理,那么我们可能只需要另一个类来将所有这些内容放入。它可以是QApplication的一个子类,或者只是一些随机的UI管理器类,但是将所有内容存储在一个地方,而不是将全局存储在一起更好。



      在这里使用单例只会打破封装并限制整个UI的可能用途。如果我们想要那些面板有两个窗口怎么办?还是多个标签(想网页浏览器)?单身人士会咬伤。当实例在许多不相关的类中被广泛访问时,它们才是非常有用的(认为DB连接,记录器,池和其他典型的单例使用)。在UI中,它们大都是无用的,因为用UI,这个东西属于那里,可能还没有其他地方,几乎总是很明显。


      I'm just starting my first fairly large Qt project which will be mostly a bunch of screens with buttons, tab widgets, and Qwt Plots. The panel stack pattern described in Qt Quarterly 27 seems pretty nice for my application. Each of my screens is a QWidget encapsulated in a Panel which is shown/hidden by a QStackedWidget. However it uses a singleton pattern for each Panel so that they aren't all created immediately as the app starts and so that more than one of each screen isn't ever created.

      So I started coding. Got the panel stack working. Added some code so that dynamically updating widgets aren't dynamically updating all the time. Got my history stack/back button working for the panels. Everything seems just fine, but I've got one nagging worry:

      1. My code smells.

      I am in no place to argue with any of the hate posted here and on blogs about the singleton pattern. I think I get it and the code I've written does make me feel a bit dirty with all the boilerplate lines and global objects. But I do like not having to worry about whether or not I already instantiated a screen before switching to it and adding it to my history stack. I just say switch to that screen, it's added to my history stack, and the magic works.

      From what I've read there are also some cases where singletons can be worthwhile. Is this one of those special cases? The magic screen switching / history stack makes me think 'yes' but the sheer number of different singleton classes I'm going to have to create makes me think 'NO no NO NO NO'.

      I want to just man up and figure out how to get the singleton pattern out of my code now so that I don't have to do it later. But I don't want to get rid of all my singleton classes just to get rid of my singleton classes because they're EVIL [citation needed].

      Any input is much appreciated!

      解决方案

      I don't really hate singletons, but this sounds like a case with no use for them. I don't understand why there are so many singletons in that article.

      First, the PanelStack is a singleton by itself. Why? If that's your main widget, then just create it on the stack in the main(), which is both cleaner and faster. If it is a part of a more complicated UI, then put it there as a member of that UI. A regular class is just fine here, making it singleton only limits its possible uses.

      Then, each panel is also a singleton? At this point even singleton lovers should begin to feel that there are too many of them already. Which is probably why you are asking this question in the first place. Let's see what real advantages singletons give here. Well, about the only advantage I can figure out from that article is the ability of lazily creating panels on the fly as they are needed. This is actually a good thing, but in fact, lazy creation and singletons are different patterns, although one often uses the other.

      Why not just put all those panels in some common container instead? In this case, the PanelStack looks like a perfect candidate for it. It is the very place where panels are stored after all. Instead of a bunch of singletons, let's create a bunch of methods in the PanelStack:

      class PanelStack : public QWidget
      {
        Q_OBJECT
      
      public:
        int addPanel(AbstractPanel *);
        void showPanel(int);
        RecordingsPanel *getRecordingsPanel();
        ReecrdingDetailsPanel *getRecordingDetailsPanel();
      
      private:
        ...
      };
      

      And so on. These get*Panel() methods can still create panels lazily as needed. Now, it's essentially the same thing as having a bunch of singletons, with some advantages added:

      • If we make panels children of the stack, they are automatically deleted when the stack is deleted. No need to worry about memory management which is always a pain with singletons.
      • You could even implement some sort of "garbage collector" in the PanelStack that deletes panels that haven't been used for some time. Or when some sort of "max active panels" limit is reached.

      Now, the only disadvantage I can think of is that we have a dependency between the stack and the panels now. But what's worse, to store instances in one class, introducing a dependency, or to store them globally? If you think that the stack should be independent from panels, which does sound reasonable, then we probably just need another class to put all those things in. It could be a subclass of QApplication, or just some random "UI manager" class, but it is still better to store everything in one place than to store everything globally.

      Using singletons here only breaks encapsulation and limits the possible uses of the whole UI. What if we want to have two windows with those panels? Or multiple tabs (think web browser)? Singletons will bite hard. And they are only really useful when the instance is accessed widely across many unrelated classes (think DB connections, loggers, pools and other typical singleton uses). They are mostly useless in an UI because with UI it is almost always obvious that "this thing belongs there, and probably nowhere else".

      这篇关于使用Qt的GUI编程中是否有单身人士?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆