2016-06-13 8 views
1

Ich möchte ein Befehlszeilenprogramm ausführen, um in einer separaten Funktion auszuführen und an die Schaltfläche weitergeleitet klicken Sie auf den zusätzlichen Befehl für dieses Programm, aber jedes Mal bekomme ich dies als eine Antwort.dauert 1 Positionsargument aber 2 wurden gegeben

dauert 1 Positions Argument aber 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() 

der Fehler

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 

kann mir einige Körper helfen

gegeben wurden es ist etwas falsch mit ** args

+1

Können wir den genauen Fehler zu sehen, und die spezifische Linie, wo es passiert – Li357

+0

'Traceback (jüngste Aufforderung zuletzt): Datei „*/subprocessExtra.py ", Zeile 33, in gui = CoreGUI (root) Datei" */subprocessExtra.py ", Zeile 18, in __init__ button = Schaltfläche (self.parent, text =" Check Device ", command = self.adb ("devices")) TypeError: adb() benötigt 1 Positionsargument, 2 hat Ausnahme ignoriert in: <__ Haupt __ StdoutRedirector Objekt bei 0x013531B0.> Attribute: 'StdoutRedirector' Objekt kein Attribut 'bündig' hat Prozess mit Exit-Code beendet 1 " – MrChaosBude

+1

, die in der Frage sein sollte: ^) – Li357

Antwort

3

Es ist, weil Sie es eine Positions Argument bieten sich hier:

button = Button(self.parent, text="Check Device", command= self.adb("devices")) 

Befehl wollen ist eine Callback-Funktion. und Sie übergeben es die Antwort von der adb Methode. (siehe hier mehr: http://effbot.org/tkinterbook/button.htm)

Wenn diese Leitung angerufen wird, wird self.adb("devices") aufgerufen. , wenn Sie bei Ihrer Definition aussehen von adb

def adb(self, **args): 

Sie sind nur für 1 Positions Argument fragen self und eine beliebige Anzahl von Keyword-Argumente **args dann sind Sie es self.adb("devices") mit 2 Positionsargumente von self Aufruf und "devices"

Was Sie tun müssen, ist eine Zwischenmethode, wenn Sie die adb Methode allgemeiner haben möchten, oder einfach setzen Sie "devices" in die adb Methode.

bearbeiten

Siehe auch hier: http://effbot.org/zone/tkinter-callbacks.htm Siehe Abschnitt "Passing Argument zu Rückrufe"

bearbeiten 2: Codebeispiel

Wenn Sie dies tun, sollte es funktionieren:

button = Button(self.parent, text="Check Device", command=lambda: self.adb("devices")) 

und dann ändern Sie Ihre Funktion n zu einem einzigen * inlieu eines ** (Stichwort arg Expansion) Siehe hier: https://stackoverflow.com/a/36908/6030424 für weitere Erläuterungen.

def adb(self, *args): 
    process = subprocess.Popen(['adb.exe', args], stdout=subprocess.PIPE, shell=True) 
    print(process.communicate()) 
    #return x.communicate(stdout) 
+0

Ich möchte Geräte nicht repariert verwenden, weil ich die gleiche Definition verwenden möchte, um andere und noch mehr agument – MrChaosBude

+0

zu erstellen, wenn ich 'button = Button hinzufügen (self.parent, text =" Check Device ", command = lambda : self.adb (self, "devices")) 'error say' button = Schaltfläche (self.parent, text = "Gerät prüfen", command = lambda: self.adb (self, "entwirft")) TypeError: adb() benötigt 2 Positionsargumente aber 3 wurden gegeben Ausnahme ignoriert in: <__ main __. StdoutRedirector Objekt bei 0x01193230> AttributError: 'StdoutRedirector' Objekt hat kein Attribut 'flush'' – MrChaosBude

+0

Beispielcode hinzugefügt. –

2

Das Problem ist in der Art und Weise Sie erklären args: es *args sein sollte (ein Stern) statt **args (zwei Sternchen). Ein Sternchen gibt eine beliebige Anzahl von Positionsargumenten an, wobei zwei Sternchen eine beliebige Anzahl von benannten Argumenten bedeuten.

Außerdem müssen Sie args richtig adb.exe passieren:

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