簡體   English   中英

如何打印另一個Tkinter腳本中調用的gui腳本的輸出?

[英]How to print output from a script in gui called in another Tkinter script?

我嘗試過使用我在網上找到的幾種不同的類似解決方案,但似乎沒有一種方法可以完成我的目標。

我想把一個外部腳本(helloworld.py)調用到我的tkinter gui中。 我希望這個名為腳本(helloworld.py)的函數在gui中按下按鈕時執行其中包含的所有函數,並將結果輸出打印到gui中,而不是控制台。 我找到了一些解決方案,將輸出打印到控制台,但我無法讓它顯示在gui中。 當我試圖讓輸出來自一個被調用的外部腳本時,我發現打印到gui的任何解決方案都不起作用。

我感謝任何幫助。 我絕對是一個新手,所以我為可能是一個基本問題而道歉,並且無法在這里提出的類似問題上為自己連接點。 下面是我目前正在使用的代碼版本之一。 預先感謝您的幫助!

import Tkinter
import sys
import subprocess
sys.path.append('/users/cmbp')

def callback():
    import os
    print subprocess.call('python /users/cmbp/p4e/helloworld.py', 
shell=True)
    lbl = Tkinter.Label(master)
    lbl.pack()

master = Tkinter.Tk()
master.geometry('200x90')
master.title('Input Test')

Btn1 = Tkinter.Button(master, text="Input", command=callback)
Btn1.pack()

master.mainloop()

編輯

我也開始嘗試將被調用的腳本作為模塊導入。 這個問題是我只能從被調用的腳本中打印出一個函數,即使我想嘗試和調用多個函數(我只是希望整個被調用的腳本打印出其函數的所有結果)。

以下是我想調用helloworld.py的腳本示例:

def cooz():
    return ('hello worldz!')

def tooz():
    return ("here is another line")

def main():
    return cooz()
    return tooz()

這是一個嘗試導入helloworld.py的tkinter gui腳本的示例:

import Tkinter as tk
import helloworld

def printSomething():
    y = helloworld.main()
    label = tk.Label(root, text= str(y))
    label.pack()


root = tk.Tk()
root.geometry('500x200')
root.title('Input Test')

button = tk.Button(root, text="Print Me", command=printSomething)
button.pack()

root.mainloop()

這導致只有第一個函數打印('hello worldz!')。 有關為什么它只會返回一行而不是整個helloworld.py腳本的任何想法?

您可以使用subprocess.check_output()來獲取輸出並分配給Label

您還可以從腳本import腳本和執行函數。

import test
test.function()

但首先,您必須使用帶有write()類重定向sys.stdout ,然后它將捕獲所有打印的文本。

您可以將sys.stdout重定向到變量(請參閱StdoutRedirector ),然后您可以編輯它(即最后的strip \\n )或者您可以直接重定向到Label (請參閱StdoutRedirectorLabel

import Tkinter as tk

# -----

import subprocess

def callback1():
    cmd = 'python test.py'

    # it will execute script which runs only `function1`
    output = subprocess.check_output(cmd, shell=True)

    lbl['text'] = output.strip()

# -----

class StdoutRedirector(object):

    def __init__(self):
        # clear before get all values
        self.result = ''

    def write(self, text):
        # have to use += because one `print()` executes `sys.stdout` many times
        self.result += text

def callback2():

    import test

    # keep original `sys.stdout
    old_stdout = sys.stdout

    # redirect to class which has `self.result`
    sys.stdout = StdoutRedirector()

    # it will execute only `function2`
    test.function2()

    # assign result to label (after removing ending "\n")
    lbl['text'] = sys.stdout.result.strip()

    # set back original `sys.stdout
    sys.stdout = old_stdout

# -----

import sys

class StdoutRedirectorLabel(object):

    def __init__(self, widget):
        self.widget = widget
        # clear at start because it will use +=
        self.widget['text'] = ''

    def write(self, text):
        # have to use += because one `print()` executes `sys.stdout` many times
        self.widget['text'] += text

def callback3():

    import test

    # keep original `sys.stdout
    old_stdout = sys.stdout

    # redirect to class which will add text to `lbl`
    sys.stdout = StdoutRedirectorLabel(lbl)

    # it will execute only `function3` and assign result to Label (with ending "\n")
    test.function3()

    # set back original `sys.stdout
    sys.stdout = old_stdout

# --- main ---

master = tk.Tk()
master.geometry('200x200')

lbl = tk.Label(master, text='')
lbl.pack()

btn1 = tk.Button(master, text="subprocess", command=callback1)
btn1.pack()

btn2 = tk.Button(master, text="StdoutRedirector", command=callback2)
btn2.pack()

btn3 = tk.Button(master, text="StdoutRedirectorLabel", command=callback3)
btn3.pack()

master.mainloop()

test.py

def function1():
    print('function 1')

def function2():
    print('function 2')

def function3():
    print('function 3')

if __name__ == '__main__':
    function1() 

在運行帶有return ...的行的方法中,在該行之后將看不到任何其他內容,如在第二行return ...實際上無效,因為return cooz() 無條件地運行。 你可以簡單地用你的main替換:

def main():
    return cooz(), tooz()

因此你的printSomething

x, y = helloworld.main()

從腳本返回所有方法/函數而不顯式傳遞方法名稱:

好吧,我有所糾正 ,基於這個答案,你可以相當簡單地做到。 為了調用所有方法或函數, 這個答案幫了很大忙。

假設有一個名為hello_world.py的腳本:

def hello_world():
    print("Hello World!")
    print("this is the 2nd line of this method")

def multiplication(*args):
    mult = 1
    for arg in args:
        mult *= arg

    return mult

def some_other_method():
    print("some other method")
    print(multiplication(2, 3, 5, 7))

以下GUI腳本位於同一目錄中:

import tkinter as tk    # required for the GUI
import subprocess       # required for redirecting stdout to GUI
import sys, inspect     # required for all methods and functions redirection
import hello_world      # the script file that is redirected

def redirect(module, method):
    '''Redirects stdout from the method or function in module as a string.'''
    proc = subprocess.Popen(["python", "-c",
        "import " + module.__name__ + ";" + module.__name__ + "." + method + "()"],
                                                                stdout=subprocess.PIPE)
    out = proc.communicate()[0]
    return out.decode('unicode_escape')

def redirect_module(module):
    '''Retruns all stdout from all methods or functions in module as a string.'''
    # to filter out non-method, and non-function attributes
    all_mtds_or_funcs = inspect.getmembers(sys.modules[module.__name__], 
                                                inspect.isfunction or inspect.ismethod)
    red_str_buffer = ""
    for method in all_mtds_or_funcs:
        red_str_buffer += redirect(module, method[0]) + "\n---\n"

    return red_str_buffer

def put_in_txt(module):
    '''Puts the redirected string in a text.'''
    txt.insert('1.0', redirect_module(module))

root = tk.Tk()
txt = tk.Text(root)
btn = tk.Button(root, text="Redirect")
btn['command'] = lambda module=hello_world : put_in_txt(module)

txt.pack()
btn.pack()

root.mainloop()

它將hello_world.py所有方法和函數的控制台輸出作為字符串返回。 根據此建議 ,然后將該字符串放在文本字段中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM