Pi GUI с существующим циклом while - PullRequest
0 голосов
/ 19 июня 2020

Я изо всех сил пытаюсь заставить простой GUI работать с python (2.7) на Raspberry Pi (Buster).

Я пробовал Tkinter и PySimple GUI, но оба они эффективно используют while циклы, и у меня уже есть такой al oop в моей программе, которая работает без проблем. И Tkinter, и PySimple GUI блокируют основной l oop.

Попытки запустить Tkinter и PySimple GUI в потоке, похоже, не работают, различные элементы не совместимы с потоками и зависают с различными ошибками Сообщения. В любом случае оказывается, что, оказавшись в потоке, вы не можете взаимодействовать с виджетами GUI, если не создадите сложные очереди, и они не являются потокобезопасными.

Все, что я пытаюсь сделать, это выписать распечатку 'Alert Door statement (последняя строка while l oop) в текстовое поле (что-нибудь красивое / красочное), а затем будет звуковой сигнал (GPIO) и кнопка, которая очищает тревожное и текстовое поле.

Любые мысли приветствуются, похоже, доступные графические интерфейсы Pi просто не подходят. Будь нежным, я новенький ie.

def vp_start_gui():
        #'''Starting point when module is the main routine.'''
                global val, w, root
                root = tk.Tk()
                top = Toplevel1 (root)
                redalert_support.init(root, top)
                root.mainloop()
                w = None


def destroy_Toplevel1():
    global w
    w.destroy()
    w = None

class Toplevel1:
    def __init__(self, top=None):
        '''This class configures and populates the toplevel window.
           top is the toplevel containing window.'''
        _bgcolor = '#d9d9d9'  # X11 color: 'gray85'
        _fgcolor = '#000000'  # X11 color: 'black'
        _compcolor = '#d9d9d9' # X11 color: 'gray85'
        _ana1color = '#d9d9d9' # X11 color: 'gray85'
        _ana2color = '#ececec' # Closest X11 color: 'gray92'
        font13 = "-family {Segoe UI} -size 22"
        font14 = "-family {Segoe UI} -size 21"

        top.geometry("480x300+267+205")
        top.minsize(120, 1)
        top.maxsize(1028, 749)
        top.resizable(1, 1)
        top.title("SecuriCode RedAlert")
        top.configure(background="#4339fb")

        self.Button1 = tk.Button(top)
        self.Button1.place(relx=0.333, rely=0.667, height=54, width=177)
        self.Button1.configure(activebackground="#ececec")
        self.Button1.configure(activeforeground="#000000")
        self.Button1.configure(background="#ffff00")
        self.Button1.configure(cursor="fleur")
        self.Button1.configure(disabledforeground="#a3a3a3")
        self.Button1.configure(font=font14)
        self.Button1.configure(foreground="#000000")
        self.Button1.configure(highlightbackground="#d9d9d9")
        self.Button1.configure(highlightcolor="black")
        self.Button1.configure(pady="0")
        self.Button1.configure(text='''Clear Alarm''')

        self.Text1 = tk.Text(top)
        self.Text1.place(relx=0.125, rely=0.133, relheight=0.423, relwidth=0.756)

        self.Text1.configure(background="white")
        self.Text1.configure(font=font13)
        self.Text1.configure(foreground="black")
        self.Text1.configure(highlightbackground="#d9d9d9")
        self.Text1.configure(highlightcolor="black")
        self.Text1.configure(insertbackground="black")
        self.Text1.configure(selectbackground="#c4c4c4")
        self.Text1.configure(selectforeground="black")
        self.Text1.configure(wrap="word")

vp_start_gui()


while 1:

    #Receive data from LAN device
    reply = s.recv(34)

    #Receive replies from SMS Gateway
    #smsreply = g.recv(34)   

    #Check for Lan device keep alive replies
    if reply.find(alivereply) != -1:
        #print 'Device alive'
        print reply

    #Check for valid Tag strings
    if reply.find(tagstring) != -1:
        print 'Tag string received'
        print reply

        #Send SMS alert message
        doorcode = reply[5:6]
        doornumber = int(doorcode, 16)
        #print doornumber

        tagcode = reply[8:9]
        tagnumber = int(tagcode, 16)
        #print tagnumber

        print 'Alert Door ' +str(doornumber) + '  Tag '  +str(tagnumber) 

Ответы [ 2 ]

1 голос
/ 19 июня 2020

И Tkinter, и PySimple GUI блокируют основной l oop.

Это не всегда верно. По моему опыту, лучшее решение, чтобы остановить tkinter от блокировки основной программы l oop использует root_window.update() вместо root_window.mainloop().

Использование этого позволит вам продолжать итерацию через ваше while l oop, а также обновлять окно tkinter.

Hope это помогает.

ОБНОВЛЕНИЕ

После вашего редактирования я сам посмотрел на ваш код.

Я изменил функцию vp_start_gui() и создал root окно за пределами l oop. Основная цель этого кода - дать вам представление о том, как go правильно реализовать ваше окно tkinter. Также о кнопках, меняющих активный фон при наведении курсора на него; tkinter.tk Кнопки не имеют этой функции по умолчанию. Под активным фоном они на самом деле подразумевают цвет фона при нажатии кнопки. Хотя есть способы сделать это с помощью tkinter.tk, я показал простой способ получить что вы хотите, используя tkinter.ttk.

import tkinter as tk
from tkinter import ttk
def vp_update_gui():
        #'''Starting point when module is the main routine.'''
                global val, w, root  
                #redalert_support.init(root, top)
                root.update()
                w = None


def destroy_Toplevel1():
    global w
    w.destroy()
    w = None

class Toplevel1:
    def __init__(self, top=None):
        '''This class configures and populates the toplevel window.
           top is the toplevel containing window.'''
        _bgcolor = '#d9d9d9'  # X11 color: 'gray85'
        _fgcolor = '#000000'  # X11 color: 'black'
        _compcolor = '#d9d9d9' # X11 color: 'gray85'
        _ana1color = '#d9d9d9' # X11 color: 'gray85'
        _ana2color = '#ececec' # Closest X11 color: 'gray92'
        font13 = "-family {Segoe UI} -size 22"
        font14 = "-family {Segoe UI} -size 21"

        top.geometry("480x300+267+205")
        top.minsize(120, 1)
        top.maxsize(1028, 749)
        top.resizable(1, 1)
        top.title("SecuriCode RedAlert")
        top.configure(background="#4339fb")

        s = ttk.Style()
        s.configure('Kim.TButton', foreground='maroon',activeforeground="yellow")
        self.Button1 = ttk.Button(top,style='Kim.TButton',text='''Clear Alarm''')
        self.Button1.place(relx=0.333, rely=0.667, height=54, width=177)


        self.Text1 = tk.Text(top)
        self.Text1.place(relx=0.125, rely=0.133, relheight=0.423, relwidth=0.756)

        self.Text1.configure(background="white")
        self.Text1.configure(font=font13)
        self.Text1.configure(foreground="black")
        self.Text1.configure(highlightbackground="#d9d9d9")
        self.Text1.configure(highlightcolor="black")
        self.Text1.configure(insertbackground="black")
        self.Text1.configure(selectbackground="#c4c4c4")
        self.Text1.configure(selectforeground="black")
        self.Text1.configure(wrap="word")


root = tk.Tk()
top = Toplevel1(root)

while 1:
    vp_update_gui()

    #Receive data from LAN device
    reply = 's.recv(34)'

    #Receive replies from SMS Gateway
    #smsreply = g.recv(34)   

    #Check for Lan device keep alive replies
    if reply == '-1':
        #print 'Device alive'
        print (reply)

    #Check for valid Tag strings
    if reply == '+1':
        print ('Tag string received')
        print (reply)

        #Send SMS alert message
        doorcode = reply[5:6]
        doornumber = int(doorcode, 16)
        #print doornumber

        tagcode = reply[8:9]
        tagnumber = int(tagcode, 16)
        #print tagnumber

        print( 'Alert Door ' +str(doornumber) + '  Tag '  +str(tagnumber) )
0 голосов
/ 22 июня 2020

Ваша проблема «блокировки» легко решается путем запуска вашей программы PySimple GUI в «асинхронном c режиме». В документации довольно много информации об использовании тайм-аутов в вызове чтения, и вы найдете множество демонстрационных программ, демонстрирующих эту технику.

Вот примерный фрагмент кода, который циклически обновляет счетчик каждые 100 миллисекунд. . Вы можете добавить опрос состояния оборудования или некоторого набора условий вместо обновления текста. Здесь вы можете добавить код для опроса чего-либо.

import PySimpleGUI as sg

layout = [  [sg.Text('My Window')],
            [sg.Text('Will output here', key='-OUT-')],
            [sg.Button('Exit')]  ]

window = sg.Window('A non-blocking window', layout)

count = 0

while True:
    event, values = window.read(timeout=100)    # returns every 100 milliseconds
    if event == sg.WIN_CLOSED or event == 'Exit':
        break
    window['-OUT-'].update(f'Count={count}')
    count += 1
window.close()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...