2016-07-29 20 views
0

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 

Antwort

4

Der Täter ist in dieser Zeile in der process_serial Funktion:

self.after(100, self.process_serial) 

Die Selbst Variable, bezieht sich auf das GUI-Objekt in hier ist, nicht zu einem tkinter-Objekt, das die Funktion 'after' hat.

Es besteht ein Konflikt zwischen Ihrem Code und dem Code aus der verknüpften Frage. Ihre Klasse erweitert kein TKinter-Objekt. Die Klasse in der Antwort erweitert die tkinter Tk-Objekt wie folgt:

class App(tk.Tk): 

Dadurch Funktionen aus der Tk-Klasse erben.

Um dies für Ihren Code zu lösen, ersetze self in der Funktion process_serial durch ein tkinter-Objekt wie self.textArea.

Alternativ können Sie tk.Tk wie in der verknüpften Antwort subclass. Aber ich sehe den Zusatznutzen hier nicht.

+0

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

+1

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

+0

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

1

Das Verfahren wurde aus afterTkinter.Tk a geerbt. Check mentioned question

wahrscheinlich sollten Sie Tkinter.Tk Unterklasse

... 
import Tkinter 
class Gui(Tkinter.Tk) 
    ...