2016-11-05 140 views
0

大家好,我是python及其模塊的新手。所以,我正在開發一款應用程序來監控辦公室照明系統。我使用tkinter來開發GUI,我嘗試在一個按鈕命令中運行一個循環,並凍結我的GUI。所以我讀了一些關於踩踏模塊的內容。 我想在循環中使用從我的變量var返回的值。我嘗試了,你可以看到下面,但函數'enable_automatico'不會調用我的線程函數'acionamento_automatico'。我沒有得到任何錯誤>覆盆子pi,tkinter和線程

#!/usr/bin/python3 
# Importando os pacotes 
import sys 
import time 
import threading 
import RPi.GPIO as GPIO 
from tkinter import ttk 
from tkinter import* 
import tkinter as tk 
from tkinter import messagebox 


#Configurando a I/O 
GPIO.setmode(GPIO.BCM) 
GPIO.setwarnings(False) 

#Configurando os pinos de Entrada 
GPIO.setup(18, GPIO.IN) #Sensor de Presença Vendas 
GPIO.setup(23, GPIO.IN) #Sensor de Luminosidade Vendas 
GPIO.setup(24, GPIO.IN) #Sensor de Presença Engenharia 
GPIO.setup(25, GPIO.IN) #Sensor de Luminosidade Engenharia 
GPIO.setup(12, GPIO.IN) #Sensor de Presença Compras 
GPIO.setup(16, GPIO.IN) #Sensor de Luminosidade Compras 
GPIO.setup(20, GPIO.IN) #Sensor de Presença Marketing 
GPIO.setup(21, GPIO.IN) #Sensor de Luminosidade Marketing 


#Configurando os pinos de Saída 
GPIO.setup(17, GPIO.OUT)#Luminária A Vendas 
GPIO.setup(27, GPIO.OUT)#Luminária B Vendas 
GPIO.setup(22, GPIO.OUT)#Luminária A Engenharia 
GPIO.setup(5, GPIO.OUT) #Luminária B Engenharia 
GPIO.setup(6, GPIO.OUT) #Luminária A Compras 
GPIO.setup(13, GPIO.OUT)#Luminária B Compras 
GPIO.setup(19, GPIO.OUT)#Luminária A Marketing 
GPIO.setup(26, GPIO.OUT)#Luminária B Marketing 



#Configurando os pinos de saída para o modo de operação manual 
GPIO.output(17, GPIO.LOW)#Luminária A Vendas 
GPIO.output(27, GPIO.LOW)#Luminária B Vendas 
GPIO.output(22, GPIO.LOW)#Luminária A Engenharia 
GPIO.output(5, GPIO.LOW) #Luminária B Engenharia 
GPIO.output(6, GPIO.LOW) #Luminária A Compras 
GPIO.output(13, GPIO.LOW)#Luminária B Compras 
GPIO.output(19, GPIO.LOW)#Luminária A Marketing 
GPIO.output(26, GPIO.LOW)#Luminária B Marketing 


#Definição da fonte de texto 
LARGE_FONT = ("Verdana", 22) 
MEDIUM_FONT = ("Verdana", 16) 
SMALL_FONT = ("Verdana", 12) 



#A class thread 

class MyThread(threading.Thread): 
    def __init__(self, threadID, name, counter): 
     threading.Thread.__init__(self) 
     self.threadID = threadID 
     selfname = name 
     self.counter=counter 


def acionamento_automatico(thread1, counter): 

    while (app.frames[Acionamento].var.get()==2): 

     if ((GPIO.input(18)==False) and (GPIO.input(23)==False)): 
      GPIO.output(17, GPIO.HIGH) 
      GPIO.output(27, GPIO.LOW) 
      app.frames[Acionamento].vendasFrame.luminaria_esquerdaFramev.label6.configure(text="Ligado") 
      app.frames[Acionamento].vendasFrame.luminaria_direitaFramev.label7.configure(text="Desligado") 

     if ((GPIO.input(18)==True) and (GPIO.input(23)==False)): 
      GPIO.output(17, GPIO.LOW) 
      GPIO.output(27, GPIO.LOW) 
      app.frames[Acionamento].vendasFrame.luminaria_esquerdaFramev.label6["text"]="Desligado" 
      app.frames[Acionamento].vendasFrame.luminaria_direitaFramev.label7["text"]="Desligado" 

     if ((GPIO.input(18)==False) and (GPIO.input(23)==True)): 
      GPIO.output(17, GPIO.HIGH) 
      GPIO.output(27, GPIO.HIGH) 
      app.frames[Acionamento].vendasFrame.luminaria_esquerdaFramev.label6["text"]="Ligado" 
      app.frames[Acionamento].vendasFrame.luminaria_direitaFramev.label7["text"]="Ligado" 


     if ((GPIO.input(18)==True) and (GPIO.input(23)==False)): 
      GPIO.output(17, GPIO.LOW) 
      GPIO.output(27, GPIO.LOW) 
      app.frames[Acionamento].vendasFrame.luminaria_esquerdaFramev.label6["text"]="Desligado" 
      app.frames[Acionamento].vendasFrame.luminaria_direitaFramev.label7["text"]="Desligado" 

    thread1.exit() 

#Habilitar modo automático 
def enable_automatico(): 

    automatico_message = messagebox.showinfo(title="Modo Automático", message = "O acionamento das luminárias será feito conforme luminosidade e pessoas no setor, resultando num menor consumo de energia") 

    app.frames[Acionamento].vendasFrame.luminaria_esquerdaFramev.lev_button.configure(state=DISABLED) 
    app.frames[Acionamento].vendasFrame.luminaria_direitaFramev.ldv_button.configure(state=DISABLED) 
    app.frames[Acionamento].engenhariaFrame.luminaria_esquerdaFramee.lee_button.configure(state=DISABLED) 
    app.frames[Acionamento].engenhariaFrame.luminaria_direitaFramee.lde_button.configure(state=DISABLED) 
    app.frames[Acionamento].comprasFrame.luminaria_esquerdaFramec.lec_button.configure(state=DISABLED) 
    app.frames[Acionamento].comprasFrame.luminaria_direitaFramec.ldc_button.configure(state=DISABLED) 
    app.frames[Acionamento].marketingFrame.luminaria_esquerdaFramem.lem_button.configure(state=DISABLED) 
    app.frames[Acionamento].marketingFrame.luminaria_direitaFramem.ldm_button.configure(state=DISABLED) 
    app.frames[Acionamento].vendasFrame.luminaria_esquerdaFramev.lev_button.update() 
    app.frames[Acionamento].vendasFrame.luminaria_direitaFramev.ldv_button.update() 
    app.frames[Acionamento].engenhariaFrame.luminaria_esquerdaFramee.lee_button.update() 
    app.frames[Acionamento].engenhariaFrame.luminaria_direitaFramee.lde_button.update() 
    app.frames[Acionamento].comprasFrame.luminaria_esquerdaFramec.lec_button.update() 
    app.frames[Acionamento].comprasFrame.luminaria_direitaFramec.ldc_button.update() 
    app.frames[Acionamento].marketingFrame.luminaria_esquerdaFramem.lem_button.update() 
    app.frames[Acionamento].marketingFrame.luminaria_direitaFramem.ldm_button.update() 

    global thread1 
    thread1 = MyThread(1, "Thread-1", 1) 
    thread1.start() 
+0

也許使用'root.after(毫秒爲單位,執行)'定期執行的功能,你將不需要你的循環和線程。 – furas

+0

至於'acionamento_automatico'不是'Thread'類的一部分,所以'enable_automatico'不能啓動它。你必須使用名字'run()'。 – furas

+0

我將在這個應用程序有更多的線程。你能給我的代碼使用線程的實例嗎?我很迷茫... – armf1993

回答

0

線程運行的代碼是在其功能run()但你沒有它

from threading import Thread 
import time 

# ----- 

def my_function(name, counter): 
    for x in range(counter): 
     print(name, x) 
     time.sleep(0.5) 

# ----- 

class MyThread(Thread): 

    def run(self): 
     my_function("Hello", 10) 

# ----- 

thread = MyThread() 
thread.start() 

或者你可以做短

from threading import Thread 
import time 

# ----- 

def my_function(name, counter): 
    for x in range(counter): 
     print(name, x) 
     time.sleep(0.5) 

# ----- 

thread = Thread(target=my_function, args=("World", 10)) 
thread.start() 

編輯: ex充足的如何控制線程並停止它。

順便說一句:在某些情況下,您應該使用queue與線程進行通信。只有主線程應該使用print()與GUI就像tkinter

from threading import Thread 
import time 

# ----- 

def my_function(name, counter): 
    for x in range(counter): 
     if stop: 
      print('STOP') 
      break 
     print(name, x) 
     time.sleep(0.5) 

# ----- 

stop = False 

thread = Thread(target=my_function, args=("World", 20)) 

print("alive 0:", thread.is_alive()) # False 

thread.start() 

print("alive 1:", thread.is_alive()) # True 

time.sleep(2) 

print("alive 2:", thread.is_alive()) # True 

time.sleep(2) 

print("alive 3:", thread.is_alive()) # True 
stop = True 
print("alive 4:", thread.is_alive()) # True 

time.sleep(2) 

print("alive 5:", thread.is_alive()) # False 

# wait till thread ends 
thread.join() 

print("alive 5:", thread.is_alive()) # False 
+0

Furas謝謝你。它很好,我只收到na錯誤,說我的線程不在tkinter的主循環中。我該如何處理這個異常? – armf1993

+0

顯示此選項 - 全文。線程必須在'root.mainloop()'之前創建/啓動。順便說一句:我的代碼中沒有看到'mainloop()' - 沒有它,tkinter就無法運行(除非在使用'tkinter'的IDLE中運行並運行'mainloop()')。你必須在關閉tkinter窗口之前停止線程。因爲線程會嘗試使用在關閉窗口時被刪除的tkinter元素。 – furas

+0

好吧傳說,得到它並修復它。謝謝!! – armf1993