需要 1 个位置参数,但给出了 2 个

MrC*_*ude 6 python subprocess tkinter popen python-3.x

我想运行一个命令行工具以在单独的函数中运行并传递给按钮单击此程序的附加命令,但每次我都将其作为响应。

需要 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()
Run Code Online (Sandbox Code Playgroud)

错误

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
Run Code Online (Sandbox Code Playgroud)

身体能帮帮我吗

**args 有问题

Tom*_*tyn 4

这是因为您在这里为其提供了一个位置参数:

button = Button(self.parent, text="Check Device", command= self.adb("devices"))
Run Code Online (Sandbox Code Playgroud)

命令需要一个回调函数。并且您将方法的响应传递给它adb。(更多信息请参见此处:http://effbot.org/tkinterbook/button.htm

当该线路被呼叫时,self.adb("devices")正在被呼叫。如果你看看你的定义adb

def adb(self, **args):
Run Code Online (Sandbox Code Playgroud)

您只需要 1 个位置参数self和任意数量的关键字参数,然后使用 2 个位置参数和**args来调用它self.adb("devices")self"devices"

如果您想让该方法更通用,adb或者只是将其放入"devices"adb方法中,您需要做的是有一个中间方法。

编辑

另请参阅此处: http: //effbot.org/zone/tkinter-callbacks.htm请参阅“将参数传递给回调”部分

编辑2:代码示例

如果你这样做,它应该有效:

button = Button(self.parent, text="Check Device", command=lambda:  self.adb("devices"))
Run Code Online (Sandbox Code Playgroud)

然后将您的函数更改为(关键字 arg 扩展)*的单个替代项**请参阅此处: 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)
Run Code Online (Sandbox Code Playgroud)