Frage von Jupitercrafter, 49

Wie kann ich mehrere Tkinter entry Felder für ein Programm Nutzen?

Hey, Ich habe ein kleines Problem mit meinem Python Programm. Ich habe versucht meine Spam Programm in eine kleine GUI einzufügen doch bislang ohne erfolg. Mit der normalen Input Funktion funktioniert das Programm doch nicht mit tkinter, hier der Code:

import pyautogui, time, sys
from tkinter import *

def spam(eingabe, wieoft, zeitabstand):
    eingabe = ment.get()
    wieoft = ment2.get()
    zeitabstand = ment3.get()
    time.sleep(zeitabstand)
    counter = wieoft
    countertext = "Noch"
    countertext2 = "verbleibend"

    while wieoft > 0:
        pyautogui.typewrite(eingabe)
        pyautogui.press('enter')
        print(countertext,counter,countertext2)
        wieoft = wieoft - 1
        counter = counter - 1
        return
mGui = Tk()

ment = StringVar()
ment2 = IntVar()
ment3 = IntVar()

mGui.title("Spam")

mbutton = Button(mGui, text = "Spam", command = spam).pack()

mEntry = Entry(mGui, text = ment).pack()
mEntry2 = Entry(mGui, number = ment2).pack()
mEntry3 = Entry(mGui, number2 = ment3).pack()

Ich habe schon mehere kleineere Programme mit jeweils nur einem Entry Feld versucht zu programmieren womit ich keine Probleme hatte:

from tkinter import *
def mhello():
    mtext = ment.get()
    mlabel2 = Label(mGui,text=mtext).pack()
    return

mGui = Tk()
ment = StringVar()


mbutton = Button(mGui,text = "OK", command = mhello).pack()

mEntry = Entry(mGui,textvariable=ment).pack()


mGui.mainloop()

Ich hoffe ihr könnt mir sagen was ich falsch mache. Mfg Tom!

Antwort
von karajan9, 28

Also... es wäre ganz wundervoll zu wissen, was passieren sollte und was passiert -- sprich was schief läuft. Ohne diese Infos ist es schwer, dir konkret weiterzuhelfen.

Mit tkinter kenne ich mich leider nicht gut aus, aber wenn ich deinen Pythoncode ansehe... ich nehme an, dass ein Fehler hierdrin steckt:

while wieoft > 0:
...
return

Das bedeutet, dass das Programm in die Schleife reingeht und dann am Ende sofort abbricht. Die Schleife wird niemals mehr als ein Mal ausgeführt werden. Ich weiß nicht ganz, was du mit dem Code machst, aber ich vermute mal, dass du eigentlich folgendes meintest:

while wieoft > 0:
...
return

So wird die Schleife ausgeführt bist wieoft == 0, dann wird die Funktion beendet. Eigentlich kannst du dir das return am Ende dann aber auch sparen, weil die Funktion eh zu Ende ist.

Ich schreibe noch ein paar Kleinigkeiten auf, die nichts kaputt machen, aber die du trotzdem ändern könntest.

Du weist "counter = wieoft" zu, und rechnest immer "wieoft = wieoft - 1" und "counter = counter - 1". Die beiden Variablen machen genau das gleiche, eine von beiden ist überflüssig.

Es ist ziemlich unüblich, Variablen zu definieren, die man nur ein Mal für eine Ausgabe verwendet:

countertext = "Noch"
countertext2 = "verbleibend"
... print(countertext,counter,countertext2)

Üblicher wäre einfach

print("Noch", counter, "verbleibend")

Bei der while-Schleife zählst du intern ja runter. Das funktioniert zwar, üblicher ist aber, dafür eine for-Schleife zu nehmen, da man dann direkt sieht, wie oft die Schleife laufen wird, und nicht erst suchen muss, ob da ein "counter -= 1" drin steht. While-Schleifen benutzt man meistens, wenn man vorher noch nicht weiß, wie oft sie durchlaufen wird.

Die passende for-Schleife für dich wäre hier

for x in range(counter, 1, -1):
    ...

Nach dem Prinzip "range(Startpunkt, Endpunkt, Schrittweite)" (hier negativ, damit es runterzählt).

Viel Erfolg damit, wenn du noch irgendwelche Fragen hast, immer zu :-)

Kommentar von Jupitercrafter ,

Vielen Dank für die vielen Tipps und Hilfen, ich werde mich gleich dransetzen und das Programm verbessern.

Bei meinem Programm handelt es sich um ein simples Spam Programm. Mein Programm soll drei sachen Abfragen und zwar: Welche Nachricht soll es senden, wie oft soll diese gesendet werden und wie lange soll das Programm warten bis es anfängt die Nachrichten zu senden um z.B. in ein Messenger wie Skype reinzugelangen ohne das, dass Programm gleich losschreibt. Für das Schreiben is pyautogui da welches nach jeder Eingabe "Enter Drückt". Das Programm funktioniert sofern ich das ganze in einem Terminal bzw Python Konsole ausführe auch einwandfrei über die input funktion, aber ich wollte das ganze nun auch in eine GUI einbringen, was leider scheitert, hier die Fehlermeldung die ich erhalte:

Traceback (most recent call last):
File "spamguiremastered.py", line 31, in
mEntry2 = Entry(mGui, number = ment2).pack()
File "/usr/lib/python3.5/tkinter/__init__.py", line 2516, in __init__
Widget.__init__(self, master, 'entry', cnf, kw)
File "/usr/lib/python3.5/tkinter/__init__.py", line 2139, in __init__
(widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: unknown option "-number"


Ich schaffe es irgendwie nicht die Felder von tkinter mit den Funktions Parametern zu verknüpfen. Bei der input Funktion war das ganz einfach, doch mit den Entry Feldern funktioniert es überhaupt nicht...

Kommentar von karajan9 ,

Wie gesagt, mit tkinter kenne ich mich nicht wirklich aus, drum muss ich gerade auch selbst etwas gucken bzw. rumraten ;-)

Es scheint so, als würden diese Zeilen die Probleme machen:

mEntry = Entry(mGui, text = ment).pack()
mEntry2 = Entry(mGui, number = ment2).pack()
mEntry3 = Entry(mGui, number2 = ment3).pack()

Dieses number und number2 sind -- so wie du es hingeschrieben hast -- Parameter von Entry. Die sind aber nicht vorgesehen, daher die Fehlermeldung. Was du eigentlich möchtest ist

mEntry2 = Entry(mGui, textvariable=ment2).pack()
deinText = ment2.get()

Ich bin gerade aber noch am überlegen, ob dir das bei deinem Problem wirklich hilft.

Kommentar von karajan9 ,

Okay, ich bin einen Schritt weiter.

So wie ich das aufgeschrieben habe, müsste das funktionieren. Damit kannst du dir den Text, der in den Textfeldern steht in der Funktion besorgen, wie du es jetzt schon machst:

eingabe = ment.get()
wieoft = ment2.get()
zeitabstand = ment3.get()

Da du dir die Werte aber in der Funktion selbst holst, musst du an die Funktion gar keine Werte mehr übergeben.

Kommentar von Jupitercrafter ,

Hm nach dieser Veränderung sagt er missing arguments.

Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.5/tkinter/__init__.py", line 1550, in __call__
return self.func(*args)
TypeError: spam() missing 3 required positional arguments: 'eingabe', 'wieoft', and 'zeitabstand'
Kommentar von karajan9 ,

Hm, könntest du wohl deinen aktuellen Code noch mal posten? Zum Beispiel hier müsse das gehen, ohne dass wir hier so ein riesiges Chaos verursachen ;-) https://gist.github.com/

Von mir aus auch in einer neuen Antwort oder so, aber hier in den Kommentaren wird das ja recht schmal ;-)

Kommentar von Jupitercrafter ,

Ok, werde ich Morgen machen, bin schon recht Müde und muss Morgen noch arbeiten. :)

Kommentar von karajan9 ,

Na klar, viel Erfolg schon mal :-)

Kommentar von Jupitercrafter ,

Ich hatte Gestern leider keine Zeit mehr aber  ich habe den Code jetzt hochgeladen, allerdings auf Pastebin, dass nutze ich schon länger. http://pastebin.com/XttAiNxA

Kommentar von karajan9 ,

Klar, kein Problem ;-)

Also, wie schon gesagt, holt sich die Funktion die benötigten Werte aus den Textfeldern selbst. Das bedeutet, dass du der Funktion spam() nichts mehr übergeben musst (und weil du lauft Funktionskopf übergeben solltest, der nichts übergibst, kommt diese Fehlermeldung). Sprich wenn du die Argumente von spam(...) löscht und das zu spam() machst, sollte es klappen.

Die Zeilen 31-33 erfüllen zur Zeit auch keinen Zweck.

Kommentar von karajan9 ,

Noch eine Kleinigkeit: In der Schleife hat x den passenden Wert, weil du den ja runterzählst (das ist quasi der Witz daran ;-) ). Sprich anstatt wieoft kannst du in deiner Schleife x verwenden und dir die Zeile 14 sparen.

Meines Wissens nach müsste die Schleife auch bin 1 gehen und nicht bis 0, damit sie das gleiche tut, wie deine alte while-Schleife. Sicher bin ich mir da aber nicht.

Kommentar von karajan9 ,

Okay, nein, das mit dem bis 0 passte doch schon, sorry ;-)

Kommentar von Jupitercrafter ,

Danke, es funktioniert endlich :). Die Zeile 14 hatte allerdings den Sinn das ich in der Konsole sehehen kann wie viele Nachrichten noch verbleibend sind. Allerdings kann man ja das "wieoft" im print Befehl durch das X ersetzen. Ich habe allerdings noch eine generelle Frage zum Programmieren die ich jetzt schon seit einer Weile nicht beantworten kann.  Hier das update des Programms: http://pastebin.com/XttAiNxA

Nochmals, Vielen Dank! :)

Kommentar von karajan9 ,

Kein Problem, freut mich, dass es klappt :-)

Was ist denn die generelle Frage? :-D

Kommentar von Jupitercrafter ,

Das return muss mir beim kopieren und ständigen verändern des Programms ausversehen mit reingeschlichen haben, sollte dort aber nicht stehen.

Keine passende Antwort gefunden?

Fragen Sie die Community