【问题标题】:Tkinter - returning print of imported modules when button clicked to perform functionTkinter - 单击按钮执行功能时返回导入模块的打印
【发布时间】:2018-11-06 09:46:10
【问题描述】:

我编写了一些主要用于控制台的代码,但被要求为其创建一个简单的 GUI 以方便使用。在其中,我正在使用小部件设置主框架,并使用小部件命令调用我导入的函数。但是,导入的函数和模块都写入输出控制台。有没有办法在子进程运行时返回要在 GUI 中更新的输出字符串/控制台输出?

示例脚本:

import Tkinter as *
import myModule1

class MyGUI(Frame):
    def __init__(self):
    # Initialization stuff.
        self.initGUI()

    def initGUI(self):
        self.downloadButton = Button(text="Download data.")
        self.downloadButton["command"] = myModule1.function
        # This function from myModule1 will constantly print to the console as the process is performed - is there any way to have this displayed in the GUI as a ScrollBar? 

    .....

或者,有没有办法在进程运行时显示对话窗口?我问是因为我在 myModule1 及其子模块中嵌入了很多打印语句,这些语句将正在发生的事情返回到控制台。最好向用户显示那些 GUI 正在工作的用户,我将其转换为 .exe 以方便使用它的用户使用。

谢谢。

编辑:myModule1.function 的示例:

import otherModule

def function1():

    log = otherModule.function2():
    if log == True:
        print "Function 2 worked."
    elif log == False:
        print "Function 2 did not work."

但是,otherModule 中的 function2 在执行计算时会打印到控制台。此处未明确显示,但控制台输出本质上是一系列计算,然后是上面显示的示例 if/elif 子句。

【问题讨论】:

  • 我看到你还在使用 Python 2。myModule1 使用 print statements 还是使用 print function 调用,哪些可以在 Python 2.6+ 中启用?但无论如何,您可以通过捕获 sys.stdout 并将其重定向到您的 GUI 来做一些事情。
  • 关于这个主题的几个现有问题应该对您有所帮助。例如,stackoverflow.com/questions/36604900/…
  • 我使用的是打印语句,而不是函数调用。我会看看你提供的链接,谢谢!
  • 请记住,这项任务不仅仅是将标准输出重定向到您的 GUI。您可能需要使用线程,以便您可以在命令行模块中运行函数,而不会在函数运行时冻结 GUI。
  • 似乎需要线程化,因为 GUI 按钮执行的命令需要一些处理时间(约 20 分钟)。你知道在 Tkinter 中使用线程的任何好的资源吗?

标签: python user-interface tkinter subprocess console-output


【解决方案1】:

这不会非常简单,但一种方法是在您的 GUI 中创建一个方法或函数,该方法或函数写入文本小部件或其他可以轻松更新其内容的小部件。我会叫它outputMethod。然后,将此函数或方法传递给myModule1.function(outputMethod)。在 module1.function 中,将 print 语句替换为 outputMethod 调用,并为其提供适当的参数。没有看到 module1.function,很难提供一个完整的例子。在 OP 发布 myModule1 示例代码后添加以下示例。

from Tkinter import *
import myModule1

class MyGUI(Frame):

    def __init__(self, parent):
    # Initialization stuff.
        self.initGUI(parent)

    def initGUI(self, parent):
        Frame.__init__(self, parent)
        self.grid_rowconfigure(1, weight=1)
        self.grid_columnconfigure(1, weight=1)
        self.pack(expand='yes', fill='both')
        self.downloadButton = Button(self, text="Download data.")
        self.downloadButton["command"] = lambda m=self.outputMethod: myModule1.function(m)
        self.text = Text(self)
        self.downloadButton.grid(row=0, column=0)
    self.text.grid(row=1, column=0, sticky='news')
        self.sy = Scrollbar(self, command=self.text.yview)
        self.text['yscrollcommand'] = self.sy.set
        self.sy.grid(row=1, column=1, sticky='nsw')


    def outputMethod(self, the_output):
        self.text.insert('end', the_output + '\n')
        # Scroll to the last line in the text widget.
        self.text.see('end')

if __name__ == '__main__':
    # Makes the module runable from the command line.
    # At the command prompt type python gui_module_name.py
    root = Tk()
    app = MyGUI(root)
    # Cause the GUI to display and enter event loop
    root.mainloop()

现在是模块 1...

def function(log):
# Note that log is merely a pointer to 'outputMethod' in the GUI module.

log("Here is a string you should see in the GUI")
log("And this should appear after it.")
# Now demonstrate the autoscrolling set up in outputMethod...
for i in range(50):
    log("Inserted another row at line" + str(i + 2))

【讨论】:

  • 这与我一直在尝试尝试的方法并驾齐驱,但我在将您所称的 outputMethod 传递给 myModule1.function 时遇到了问题。我将编辑一个简单的示例,说明 function1 的外观。
猜你喜欢
  • 2019-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多