Python:如何为 GUI 类创建单独的模块

Posted

技术标签:

【中文标题】Python:如何为 GUI 类创建单独的模块【英文标题】:Python: How to create a separate module for the GUI class 【发布时间】:2019-02-19 04:03:55 【问题描述】:

此代码运行良好。 MyApp 是完成所有工作的类,MyGUI 是显示和请求 MyApp 数据的用户界面。

class MyGUI(): # displays results from MyApp and sends request to MyApp (e.g. fetch prices new prices)

    def __init__(self):
        print("GUI running")

    def user_request_price(self,ticker):        
        self.req_price(ticker)

    # methods I request from MyApp 
    def req_price(self,ticker): 
        app.get_price(ticker)

    # methods I receive from MyApp
    def print_price(self,val,price):
        print (val,":",price)    

class MyApp(): # does a lot of stuff, e.g. fetch prices from a server

    def __init__(self):
        self.id = 0
        self.gui = MyGUI() # start gui

    # methods called by GUI
    def get_price(self, ticker):
        if ticker == "MSFT": price = 20.23
        self.output_price(ticker,price)

    # methods sent to GUI
    def output_price(self,ticker,price):
        self.gui.print_price(ticker,price)


if __name__ == "__main__": 
    app = MyApp()
    app.gui.user_request_price("MSFT")

现在我想将 GUI 放入一个单独的模块中,因此创建一个模块文件 gui.py 并将其导入 MyApp 文件中:

from gui import *

就是这样。我在哪里挣扎:gui.py 看起来如何以及 MyGUI() 如何访问 MyApp 方法?进行这种分离是否明智?还有其他关于结构的建议吗?

【问题讨论】:

是的,可以将它们分开。通过from <module_name> import all 可以轻松导入您的后端方法 【参考方案1】:

最后我做到了——这似乎是在应用程序和 gui 之间进行清晰分离和通信的最佳方法。

桂:

import queue

def __init__(self):
    threading.Thread.__init__(self)
    self.requests = queue.Queue()  # request queue for App
    self.start()

def queue_request(self,reqId,val):
    self.requests.put([reqId,val])

应用程序:

import threading
import queue

def checkGUIQueue(self):
    threading.Timer(1.0, self.checkGUIQueue).start() # check every 1 second                
    while not self.gui.requests.empty():
        (id,value) = self.gui.requests.get()
        ... process request ...

【讨论】:

【参考方案2】:

在你的gui.py

from myapp import MyApp

class MyGUI(): # displays results from MyApp and sends request to MyApp (e.g. fetch prices new prices)

    app = MyApp()

    def __init__(self):
        print("GUI running")

    def user_request_price(self,ticker):        
        self.req_price(ticker)

    # methods I request from MyApp 
    def req_price(self,ticker): 
        app.get_price(ticker)

    # methods I receive from MyApp
    def print_price(self,val,price):
        print (val,":",price)  

在你的myapp.py 中(注意第一行),并确保两个文件都在同一个目录中,否则你必须相对更改你的导入。

from gui import MyGUI

class MyApp(): # does a lot of stuff, e.g. fetch prices from a server

    def __init__(self):
        self.id = 0
        self.gui = MyGUI() # start gui

    # methods called by GUI
    def get_price(self, ticker):
        if ticker == "MSFT": price = 20.23
        self.output_price(ticker,price)

    # methods sent to GUI
    def output_price(self,ticker,price):
        self.gui.print_price(ticker,price)

if __name__ == "__main__": 
    app = MyApp()
    app.gui.user_request_price("MSFT")

【讨论】:

"gui.py", line 11 NameError: name 'app' is not defined 我已经更新了代码,但是您的示例似乎在两个类之间有很多交错。但是,您必须始终尝试在类之间实现单向依赖。因此,当您编写代码时,请尝试将所有后端方法写入一个类并将整个类导入您的前端文件中。并且不要将您的前端方法带入您的后端类。 谢谢,但还是不行。 > ImportError: cannot import name 'MyGUI' 所以至少 pyhton 3.6。禁止相互交叉引用。您的评论提出了一个很好的观点,但如果您想将 GUI 与核心严格分开,这就是本质。 GUI 向核心发送消息并从核心接收消息。对解决这个问题的通用方法非常开放。【参考方案3】:

gui.py 文件就是

class MyGUI(): # displays results from MyApp and sends request to MyApp (e.g. fetch prices new prices)

def __init__(self):
    print("GUI running")

def user_request_price(self,ticker):        
    self.req_price(ticker)

# methods I request from MyApp 
def req_price(self,ticker): 
    app.get_price(ticker)

# methods I receive from MyApp
def print_price(self,val,price):
    print (val,":",price) 

将导入添加到 myapp.py 的顶部,一切正常。

如果有意义的话,我会尝试将我的代码分离到单独的文件中。它使阅读内容更加清晰。

【讨论】:

以上是关于Python:如何为 GUI 类创建单独的模块的主要内容,如果未能解决你的问题,请参考以下文章

如何为两个单独的 Dbus Python 程序创建 Dbus Mainloop

如何为 Autodesk Maya OSX 将 py 文件编译为 .so

在 Angular 项目中,如何为项目单独创建路由文件?

如何为 python 应用程序安装 Qt 模块

节点集群:如何为每个工作人员分配单独的服务器/端口?

如何为单线程 GUI 应用程序创建额外的工作线程?