[英]tkinter py script gives different output when called from another script
[英]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.