ich meine Arbeits tkinter Code nahm (die nur zog Fenster/Tasten und so weiter) und versuchte, einen Code aus der genehmigten Antwort hinzufügen hier: python code for serial data to print on window.‚Gui‘ Objekt hat kein Attribut ‚nach‘
Die zugelassene Antwort funktioniert selbst mit sehr kleinen Änderungen, aber zu meinem Code hinzugefügt bekomme ich den Fehler "'Gui' Objekt hat kein Attribut 'nach'"
Was ich nicht verstehe ist, warum das Attribut "nach" in gesucht wird Klasse Gui statt in der Methode process_serial.
from tkinter import *
from tkinter import ttk
import serial
import threading
import queue
class SerialThread(threading.Thread):
def __init__(self, queue):
threading.Thread.__init__(self)
self.queue = queue
def run(self):
s = serial.Serial('COM11',115200)
while True:
if s.inWaiting():
text = s.readline(s.inWaiting())
self.queue.put(text)
class Gui():
def __init__(self, master):
###MAIN FRAME###
mainFrame = Frame(master, width=50000, height=40000)
mainFrame.pack(fill = BOTH, expand = 1)
###LIST FRAME###
listFrame = Frame(mainFrame)
listFrame.pack(side = TOP, fill = BOTH, expand = 1)
self.sensorList = ttk.Treeview(listFrame)
self.sensorList["columns"]=("MAC","Type","Value","Voltage","Firmware","Rate","RSSI")
self.sensorList.column("MAC", width=200, minwidth=200)
self.sensorList.column("Type", width=100, minwidth=100)
self.sensorList.column("Value", width=100, minwidth=100)
self.sensorList.column("Voltage", width=100, minwidth=100)
self.sensorList.column("Firmware", width=100, minwidth=100)
self.sensorList.column("Rate", width=100, minwidth=100)
self.sensorList.column("RSSI", width=100, minwidth=100)
self.sensorList.heading("MAC", text="MAC")
self.sensorList.heading("Type", text="Type")
self.sensorList.heading("Value", text="Value")
self.sensorList.heading("Voltage", text="Voltage")
self.sensorList.heading("Firmware", text="Firmware")
self.sensorList.heading("Rate", text="Rate")
self.sensorList.heading("RSSI", text="RSSI")
self.sensorList.pack(fill = BOTH, expand = 1, pady=5, padx=5)
###TEXT AREA FRAME###
textAreaFrame = Frame(mainFrame)
textAreaFrame.pack(side = TOP, fill = BOTH, expand = 1)
self.textArea = Text(textAreaFrame)
self.textArea.pack(fill = BOTH, expand = 1, pady=5, padx=5)
###INPUT FRAME###
inputFrame = Frame(mainFrame)
inputFrame.pack(side = BOTTOM, fill = X, expand = 0)
self.input = Entry(inputFrame)
self.input.pack(side=LEFT, fill = X, expand = 1, pady=5, padx=5)
self.comboAction = ttk.Combobox(inputFrame)
self.comboAction.pack(side = LEFT, pady=5, padx=5)
self.comboDevice = ttk.Combobox(inputFrame)
self.comboDevice.pack(side = LEFT, pady=5, padx=5)
self.sendButton = Button(
inputFrame, text="SEND", command=mainFrame.quit
)
self.sendButton.pack(side=LEFT,pady=5, padx=5)
#self.button = Button(
# mainFrame, text="QUIT", fg="red", command=mainFrame.quit
#)
#self.button.pack(side=LEFT)
#self.hi_there = Button(mainFrame, text="Hello", command=self.say_hi)
#self.hi_there.pack(side=LEFT)
###AFFIX MINIMUM SIZE OF MAIN WINDOW TO PREVENT POOR SIZING###
master.update()
master.minsize(root.winfo_width(), root.winfo_height())
master.minsize(master.winfo_width(), master.winfo_height())
###SERIAL PORT###
self.queue = queue.Queue()
thread = SerialThread(self.queue)
thread.start()
self.process_serial()
def process_serial(self):
while self.queue.qsize():
try:
self.textArea.delete(1.0, 'end')
self.textArea.insert('end', self.queue.get())
except Queue.Empty:
pass
self.after(100, self.process_serial)
def say_hi(self):
s = self.input.get()
print ("hi there, everyone!" + s)
root = Tk()
gui = Gui(root)
root.mainloop()
root.destroy() # optional; see description below
Vielen Dank. Das hat funktioniert, aber ich muss einige Zeit damit verbringen, wirklich zu verstehen, was passiert ist. Nachdem das gelöst wurde, schließt mein Programm nicht richtig. Ich meine, ich werde nicht zurück in die cmd-Zeile übernommen, und nichts passiert, wenn ich STRG + C drücke. Ich entfernte das letzte root.destroy(), weil es einen Fehler warf, der sagt, dass es bereits zerstört ist. Liegt es daran, dass ich diese process_serial-Schleife ausgeführt habe? – HSPalm
Die Schließen-Schaltfläche Ihrer Anwendung wird standardmäßig zerstört. Es kommt dann aus der Funktion root.mainloop() und versucht, root.destroy() aufzurufen. Dies scheitert, weil es bereits zerstört wurde. root.destroy() ist daher nicht notwendig. Sie sollten nicht zurück in die cmd-Zeile gebracht werden, da der Hauptpfad() ausgeführt wird. Um Ihre Anwendung zu beenden, wenn Sie Strg-C drücken, setzen Sie thread.daemon für den Thread auf True. – Munchhausen
Siehe: https://docs.python.org/3/library/threading.html#threading.Thread.daemon und siehe: http://effbot.org/tkinterbook/widget.htm#Tkinter.Widget.mainloop-method – Munchhausen