简体   繁体   English

Python与GUI(PyQt)程序中的语句

[英]Python with statement in GUI (PyQt) program

I'm trying to combine python resource management within a PyQt GUI application. 我正在尝试在PyQt GUI应用程序中组合python资源管理。

Target: 目标:

  • Allocate a resource (eg open a file) as a reaction to GUI event 分配资源(例如,打开文件)作为对GUI事件的反应
  • Keep a handle to this resource within my application (maybe the GUI object) 在我的应用程序中保留此资源的句柄(可能是GUI对象)
  • Clean up resource properly, when it is no longer needed (latest when the application closes, potentially in reaction to a GUI event) 在不再需要资源时正确清理资源(应用程序关闭时最新,可能是对GUI事件的反应)

How do I combine this in a nice way? 我如何以一种很好的方式结合这个?

As it is now programmed, widget.getResource will allocate and release the resource right away. 现在编程, widget.getResource将立即分配和释放资源。 However, I cannot yield from the function either, as then the allocation would never be executed. 但是,我不能yield从功能无论是作为然后分配永远不会被执行。 I could place the context in the main part, but I want to use some information from GUI (eg which resource to allocate), so I need a main event loop before I can enter. 我可以将上下文放在主要部分,但我想使用GUI中的一些信息(例如,要分配哪个资源),所以我需要一个主事件循环才能进入。

Example code: 示例代码:

# Resource context manager:
import contextlib
def allocateResource():
    print('allocated')

def releaseResource():
    print('released')

@contextlib.contextmanager
def resourceContext():
    allocateResource()
    try:
        yield 'special resource'
    finally:
        releaseResource()

# PyQt Widget:
from PyQt4.QtGui import QWidget, QPushButton, QApplication, QVBoxLayout

class widget(QWidget):

    def __init__(self, parent=None):
        super(widget, self).__init__(parent=parent)

        self.button1 = QPushButton('Get Resource')
        self.button1.clicked.connect(self.getResource)

        self.setLayout(QVBoxLayout())
        self.layout().addWidget(self.button1)

    def getResource(self):
        print('getting resource')
        with resourceContext() as r:
            print('now I can use ', r)

        print('Ouch. Leaving context again')

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    main = widget()
    main.show()
    # directly emulate click
    main.button1.clicked.emit(True)

    sys.exit(app.exec_())

You're right, you can't use a context manager for this since the resource allocation is open-ended. 你是对的,你不能使用上下文管理器,因为资源分配是开放式的。 You'll have to keep track of the resource and deallocate it manually whenever you're done with it. 您必须跟踪资源并在完成后手动取消分配资源。

If it's a resource that typically won't be deallocated until you close your application then you could do that by overriding the closeEvent method. 如果它是一个通常在您关闭应用程序之前不会被释放的资源,那么您可以通过重写closeEvent方法来实现。

class widget(QWidget):
    ...
    def getResource(self):
        if not self.resource:
            self.resource = allocateResource()
        return self.resource

    def closeEvent(self, event):
        if self.resource:
            releaseResource()
        super(widget, self).closeEvent(event)

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

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