コマンドラインツールを実行して別の関数で実行し、ボタンに渡してこのプログラムの追加コマンドをクリックしたいのですが、これを応答として受け取るたびに。
1つの位置引数を取りますが、2つが与えられました
from tkinter import *
import subprocess
class StdoutRedirector(object):
def __init__(self,text_widget):
self.text_space = text_widget
def write(self,string):
self.text_space.insert('end', string)
self.text_space.see('end')
class CoreGUI(object):
def __init__(self,parent):
self.parent = parent
self.InitUI()
button = Button(self.parent, text="Check Device", command= self.adb("devices"))
button.grid(column=0, row=0, columnspan=1)
def InitUI(self):
self.text_box = Text(self.parent, wrap='Word', height = 6, width=50)
self.text_box.grid(column=0, row=10, columnspan = 2, sticky='NSWE', padx=5, pady=5)
sys.stdout = StdoutRedirector(self.text_box)
def adb(self, **args):
process = subprocess.Popen(['adb.exe', args], stdout=subprocess.PIPE, Shell=True)
print(process.communicate())
#return x.communicate(stdout)
root = Tk()
gui = CoreGUI(root)
root.mainloop()
エラー
Traceback (most recent call last):
File "C:/Users/Maik/PycharmProjects/Lernen/subprocessExtra.py", line 33, in <module>
gui = CoreGUI(root)
File "C:/Users/Maik/PycharmProjects/Lernen/subprocessExtra.py", line 18, in __init__
button = Button(self.parent, text="Check Device", command= self.adb("devices"))
TypeError: adb() takes 1 positional argument but 2 were given
Exception ignored in: <__main__.StdoutRedirector object at 0x013531B0>
AttributeError: 'StdoutRedirector' object has no attribute 'flush'
Process finished with exit code 1
誰かが私を助けることができます
** argsに問題があります
これは、ここで位置引数を提供しているためです。
button = Button(self.parent, text="Check Device", command= self.adb("devices"))
コマンドwantはコールバック関数です。 adb
メソッドからの応答を渡します。 (詳細はこちらをご覧ください: http://effbot.org/tkinterbook/button.htm )
その行が呼び出されると、self.adb("devices")
が呼び出されます。 adb
の定義を見ると
def adb(self, **args):
1つの位置引数self
と任意の数のキーワード引数**args
のみを要求している場合、self.adb("devices")
を2つの位置引数self
と"devices"
で呼び出します。
adb
メソッドをより一般的にしたい場合、または"devices"
をadb
メソッドに入れる場合は、中間メソッドを使用する必要があります。
edit
こちらもご覧ください: http://effbot.org/zone/tkinter-callbacks.htm 「引数をコールバックに渡す」セクションを参照してください
編集2:コード例
これを行うと、うまくいくはずです。
button = Button(self.parent, text="Check Device", command=lambda: self.adb("devices"))
次に、関数を*
(キーワード引数展開)の代わりに単一の**
に変更します。詳細については、ここを参照してください: https://stackoverflow.com/a/36908/6030424 。
def adb(self, *args):
process = subprocess.Popen(['adb.exe', args], stdout=subprocess.PIPE, Shell=True)
print(process.communicate())
#return x.communicate(stdout)
問題は、args
の宣言方法にあります。*args
(2つのアスタリスク)ではなく、**args
(1つのアスタリスク)である必要があります。 1つのアスタリスクは任意の数の位置引数を指定しますが、2つのアスタリスクは任意の数の名前付き引数を意味します。
また、args
をadb.exe
に正しく渡す必要があります。
def adb(self, *args):
process = subprocess.Popen(['adb.exe'] + args, stdout=subprocess.PIPE, Shell=True)