简体   繁体   English

Python Pyside QT-在CLI上运行时防止由于导入导致的QT初始化

[英]Python Pyside QT - Prevent Initialization of QT due to imports when running on CLI

So we have a rather large program written in Python using PySide/QT to get most of its GUI work done. 因此,我们有一个使用PySide / QT用Python编写的相当大的程序,可以完成大部分GUI工作。 We use Chaco to do some plotting. 我们使用Chaco做一些绘图。

This program also has a full CLI interface. 该程序还具有完整的CLI界面。

Every now and then a developer accidentally creates an import chain that causes our CLI runs to try and import something from PySide or Chaco. 开发人员时不时地不小心创建了一个导入链,导致我们的CLI运行尝试从PySide或Chaco导入某些内容。 This causes our CLI runs to die with "cannot connect to x server" as either PySide or Chaco is trying to initialize X via QT. 由于PySide或Chaco试图通过QT初始化X,这导致我们的CLI运行由于“无法连接到x服务器”而终止。

Any tips on how to prevent this? 关于如何防止这种情况的任何提示? Can we stub out and override some function that is doing this? 我们可以存根并覆盖执行此操作的某些功能吗? Some flag we can pass along? 我们可以传递一些标志吗? Currently our prevention mechanism is track down the bad import and refactor. 目前,我们的预防机制是追查不良的进口和重构。

So one semi-solution is to do the following. 因此,一种半解决方案是执行以下操作。 Essentially stub out the QApplication class and have it print a stack trace on init. 本质上是将QApplication类存根,并使其在init上打印堆栈跟踪。 This will break things but you will get a stack trace to do the first spot QtApplication tries to initialize. 这会破坏事情,但是您将获得堆栈跟踪以进行QtApplication尝试初始化的第一个位置。

_oldQtApplication = QtGui.QApplication

class BogusQApplication(QtGui.QApplication):
    def __init__(self, *args):
        import traceback
        print traceback.print_stack()

        _oldQtApplication.__init__(self, args)

QtGui.QApplication = BogusQApplication

A better solution would be to essentially stub the whole QtApplication class in such a way that users of it still work but essentially have a NullQtApplication. 更好的解决方案是实质上以某种方式对整个QtApplication类进行存根,以便其用户仍然可以工作,但本质上具有NullQtApplication。 Unfortunately this appears to be a ton of work based on the usage of QtApplication in libraries like PySide of Chaco. 不幸的是,基于QtApplication在Chaco的PySide等库中的使用,这似乎需要大量工作。

Rather than avoiding initialising Qt altogether, perhaps you could use QCoreApplication in your CLI applications. 不必完全避免初始化Qt,而是可以在CLI应用程序中使用QCoreApplication。 See the detailed description of QApplication in http://doc.qt.io/qt-5/qapplication.html for some example code you could adapt. 有关您可以改编的一些示例代码,请参见http://doc.qt.io/qt-5/qapplication.html中的QApplication详细说明。

The good practice for such kind of pattern is to have a proper organisation of the code where the code using the user interface can't be imported when running on the CLI. 此类模式的良好做法是对代码进行适当的组织,以使在CLI上运行时无法导入使用用户界面的代码。

You can do that by designing your application in a pluggable way and only load the plugins needed by the CLI when running in CLI mode and the full set of plugins when running with the UI. 您可以通过以可插拔的方式设计应用程序来做到这一点,并且仅在以CLI模式运行时加载CLI所需的插件,而在以UI运行时则加载完整的插件集。 We extensively use the Envisage framework to build pluggable application and solve those kind of problems. 我们广泛使用Envisage框架来构建可插拔应用程序并解决此类问题。 It requires a bit more upfront effort in designing your app. 在设计您的应用程序时需要更多的前期工作。

For reference: 以供参考:

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM