web-dev-qa-db-ja.com

1つの位置引数を取りますが、2つが与えられました

コマンドラインツールを実行して別の関数で実行し、ボタンに渡してこのプログラムの追加コマンドをクリックしたいのですが、これを応答として受け取るたびに。

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に問題があります

3
MrChaosBude

これは、ここで位置引数を提供しているためです。

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)
3
Tom Myddeltyn

問題は、argsの宣言方法にあります。*args(2つのアスタリスク)ではなく、**args(1つのアスタリスク)である必要があります。 1つのアスタリスクは任意の数の位置引数を指定しますが、2つのアスタリスクは任意の数の名前付き引数を意味します。

また、argsadb.exeに正しく渡す必要があります。

def adb(self, *args):
    process = subprocess.Popen(['adb.exe'] + args, stdout=subprocess.PIPE, Shell=True)
4
Hai Vu