2015-06-18 3 views
0

Я очень новичок в Python (и программирование по большей части), и я работаю над проектом, чтобы получить код Морзе и выслушайте код Морзе между маяками.Python Пока цикл в Tkinter?

У меня есть маяк, возможно, не лучший код, но он работает, однако, когда цикл начинается, экран Tkinter замерзает, и кнопка остановки маяка не работает, пока все маяки не будут завершены.

Я хотел бы запустить маяк бесконечно и просто использовать кнопку остановки маяка, чтобы остановить его, но до сих пор я не могу понять, как остановить цикл.

#!usr/bin/env python 

import sys 
import re 
import tkMessageBox 
from Tkinter import * 
import pygame 
import time 


CODE = {'A': '.-',  'B': '-...', 'C': '-.-.', 
    'D': '-..', 'E': '.',  'F': '..-.', 
    'G': '--.', 'H': '....', 'I': '..', 
    'J': '.---', 'K': '-.-', 'L': '.-..', 
    'M': '--',  'N': '-.',  'O': '---', 
    'P': '.--.', 'Q': '--.-', 'R': '.-.', 
    'S': '...', 'T': '-',  'U': '..-', 
    'V': '...-', 'W': '.--', 'X': '-..-', 
    'Y': '-.--', 'Z': '--..', 

    '0': '-----', '1': '.----', '2': '..---', 
    '3': '...--', '4': '....-', '5': '.....', 
    '6': '-....', '7': '--...', '8': '---..', 
    '9': '----.' 
    } 

ONE_UNIT = 0.5 
THREE_UNITS = 3 * ONE_UNIT 
SEVEN_UNITS = 7 * ONE_UNIT 
PATH = 'morse_sound_files/' 

def verify(string): 
keys = CODE.keys() 
for char in string: 
    if char.upper() not in keys and char != ' ': 
     sys.exit('Error the charcter ' + char + ' cannot be translated to Morse Code') 




beaconout = '' 
beaconTEXT = 'this is text that is default' 
def ask_quit(): 
if tkMessageBox.askokcancel("Quit", "are you sure you want to quit?"): 
    root.destroy() 

def getinput(): 
incomingTEXT = incoming.get() 
outboundTEXT = outbound.get() 
beaconTEXT = beaconmessage.get(1.0,"end") 
beaconout = outboundTEXT+" "+outboundTEXT+" "+outboundTEXT+" "+beaconTEXT+""+incomingTEXT 
print beaconout 
beaconout = beaconout.replace('\n', ' ') 
print beaconout 
print 'Welcome to Alphabet to Morse Code Translator v.01' 
msg = beaconout 
#verify(msg) 
print 
pygame.init() 

for char in msg: 
    if char == ' ': 
     print ' '*7, 
     time.sleep(SEVEN_UNITS) 
    else: 
       print CODE[char.upper()], 
       pygame.mixer.music.load(PATH + char.upper() + '_morse_code.ogg') 
       pygame.mixer.music.play() 
       time.sleep(THREE_UNITS) 




root = Tk() 
root.geometry("800x600+300+300") 
frame = Frame(root, width=1000, height=600) 
label1 = Label(root, text="To: Call Sign:") 
label2 = Label(root, text="Your Call Sign:") 
label3 = Label(root, text="Enter your message:") 

outbound = StringVar() 
outboundcallsign = Entry(root, textvariable=outbound) 

incoming = StringVar() 
inboundcallsign = Entry(root, textvariable=incoming) 

beacon = StringVar() 
beaconmessage = Text(root, height=1, width=30) 

label1.grid(row=1, sticky=E) 
label2.grid(row=2, sticky=E) 
label3.grid(row=3, sticky=E) 

outboundcallsign.grid(row=1, column=1) 
inboundcallsign.grid(row=2, column=1) 
beaconmessage.grid(row=4, columnspan=4) 

cbox = Checkbutton(root, text="message is ready to beacon?") 
cbox.grid(columnspan=2) 
submitbut = Button(root,text="Start Beacon", command = getinput) 
submitbut.grid(row=14,column=1) 
submitbut.bind("<Button-1>") 

cancelbut = Button(root,text="Stop Beacon", command=ask_quit) 
cancelbut.grid(row=14, column=3) 

root.mainloop() 
+1

Трудно воспроизвести ваш вопрос, но проблема заключается в том, что поток пользовательского интерфейса заблокирован. Либо поставьте материал из 'getinput' в поток, либо перепишите свой цикл' for char in msg', используя 'root.after' вместо' sleep' –

ответ

1

«Я хотел бы запустить маяк бесконечно и просто использовать кнопку остановки радиомаяка, чтобы остановить»

Запуск «Маяк» код в отдельном процессе, как вы хотите сделать 2 вещи в в то же время, [1] Маяк и [2] проверьте, чтобы кнопка нажата (хотя может быть возможно найти творческий способ использования «после», чтобы проверить нажатие кнопки, ИМХО, это более очевидно и меньше проблем сделать это путь). Кнопка quit отменяет процесс. В этом примере для простоты используется счетчик вместо кода маяка.

from multiprocessing import Process 
from functools import partial 

try: 
    import Tkinter as tk ## Python 2.x 
except: 
    import tkinter as tk ## Python 3.x 

class ProgressBar(): 
    def __init__(self, root): 
     self.root=root 
     self.root.geometry("75x50+900+100") 
     self.ctr=1 

    def counter(self): 
     """ a separate process in a separate GUI 
     """ 
     self.top_count=tk.Toplevel(self.root) 
     self.top_count.geometry("75x50+750+50") 
     self.label_ctr = tk.IntVar() 
     self.label_ctr.set(self.ctr) 
     label = tk.Label(self.top_count, textvariable=self.label_ctr) 
     label.pack() 
     self.change_counter() 

    def change_counter(self): 
     self.ctr += 1 
     self.label_ctr.set(self.ctr) 
     self.top_count.after(750, self.change_counter) 


def stop_process(process_id, PB): 
    process_id.terminate() 
    PB.top_count.destroy() ## destroy Toplevel to stop "after" 

    ## shut down Tkinter 
    ##root.quit() 

root = tk.Tk() 

PB=ProgressBar(root) 
pr1=Process(target=PB.counter(), args=()) 
pr1.start() 

tk.Button(root, text="Exit", bg="orange", 
      command=partial(stop_process, pr1, PB)).pack() 
root.mainloop() 

Если вы не хотите, чтобы уничтожить TopLevel, то вы можете использовать переменную, в следующем случае, когда изменяются эти 2 Funtions, СУУ> 0 Для обмена данными между двумя процессами требует словаря менеджера или списка, однако ,

def change_counter(self): 
    self.ctr += 1 
    self.label_ctr.set(self.ctr) 
    if self.ctr > 0: 
     self.top_count.after(750, self.change_counter) 


def stop_process(pr1, PB): 
    PB.ctr = -10 
    pr1.terminate() 
## PB.top_count.destroy() 
+0

Хм, я действительно хотел сдержать это в том же фрейме, и честно я нужно делать несколько вещей одновременно, мне еще предстоит развить другое прослушивание, декодировать и печатать декодированные текстовые функции, но мое намерение состоит в том, чтобы слушать, когда на самом деле не маячит, если прослушивание декодирует ожидаемый знак вызова, тогда мы будем напечатайте декодированное сообщение на тот же фрейм, который мы используем для ввода и запуска маяка. Возможно ли это с Python или я превысил возможности Python, пытаясь это сделать? – Daniac

+0

Вы можете, конечно, изменить Toplevel на фрейм и использовать один из двух методов выше. Если вам нужно много экземпляров одновременно, то функция stop_process(), а также все, что вы можете добавить, должны находиться в одном классе, если вы хотите их остановить отдельно. Затем вы запускаете отдельный процесс для каждого экземпляра класса. –

Смежные вопросы