I'm doing a graphical interface with Gtk in python, and I have a serial script that keeps sending and receiving data from a microcontrolled system. The script of the serial is in an infinite loop (while True :), since the interface enters Gtk.main () and is locked in there. I need the two to be opened and executed together, I've tried multiprocessing but one code only opens when the other is closed. So I need to know how I can do this if there is another specific module.
! / usr / bin / python3
import gi import multiprocessing import import subprocess import threading import Modulo_Serial
from multiprocessing import Process, Pipe from subprocess import call gi.require_version ("Gtk", "3.0") from gi.repository import Gtk, GObject from datetime import datetime
class Application (object):
def __init__(self):
#VALORES INICIAS DE VARIÁVEIS
self.flag_tela_inicial = 0
self.flag_tela_principal = 1
self.flag_tela_config01 = 1
self.flag_tela_config02 = 1
self.flag_tela_teste01 = 1
self.flag_leitura_arquivo = 0
self.timer_inicial = 0
self.timer_tela_config01 = 0
self.timer_tela_config02 = 0
self.timer_tela_teste01 = 0
self.timer_tela_teste02 = 0
self.timer_tela_teste03 = 0
self.timer_tela_teste04 = 0
self.flag_volume_init = 0
self.valor_teclado = 0
self.contador_teclado = 0
self.contador_teclado2 = 0
self.pressao_set_valor = 0
self.tempo_set_valor = 0
#DEFINICOES DE ABERTURA DAS TELAS
def tela_teclado01(self, flag_funcao):
if (flag_funcao == 0):
tela_teclado01_builder = Gtk.Builder()
tela_teclado01_builder.add_from_file("tela_teclado01.glade")
self.janela = tela_teclado01_builder.get_object("janela")
self.janela.show()
else:
pass
def tela_inicializacao(self, flag_funcao):
if(flag_funcao == 0):
tela_inicial_builder = Gtk.Builder()
tela_inicial_builder.add_from_file("tela_inicial.glade")
self.qwr_txt = tela_inicial_builder.get_object("wrs_txt")
self.tourniquet_txt = tela_inicial_builder.get_object("logo_txt")
self.bemvindo_txt = tela_inicial_builder.get_object("bemvindo_txt")
self.janela_inicial = tela_inicial_builder.get_object("janela")
self.texto_inicial = tela_inicial_builder.get_object("texto_inicial_txt")
try:
self.arquivo_config = open("data/config.dat", "r")
self.linha01 = self.arquivo_config.readline()
self.arquivo_config.close()
try:
self.linha01 = int(self.linha01)
except:
self.linha01 = 1
self.num_idioma = self.linha01
except:
print("*Erro ao abri arquivo config.dat tela inicial")
#COLOCANDO HORA E DATA ATUAL NAS CONFIGURAÇÕES DE HORA
data_hora = datetime.now()
self.data_config_txt.set_text(str(data_hora.day) + "/" + str(data_hora.month) + "/" + str(data_hora.year) )
self.hora_config_txt.set_text(str(data_hora.hour)+ ":"+ str(data_hora.minute))
#CONECTANDO OS SINAIS DO XML
tela_configuracao01_builder.connect_signals({ "avancar01_bt_clicked" : self.bt_avancar_confing01,
"restautar_bt_clicked" : self.botao_restaura_default,
"idioma_cb_changed" : self.selecao_idioma,
"tempo_cb_changed" : self.selecao_tempo,
"volume_bt_clicked" : self.botao_volume_init,
"pressao_set_bt_clicked" : self.botao_set_pressao,
"tempo_set_bt_clicked" : self.botao_set_tempo,
"tecla_1_clicked" : self.botao_tecla_1,
"tecla_2_clicked" : self.botao_tecla_2,
"tecla_3_clicked" : self.botao_tecla_3,
"tecla_4_clicked" : self.botao_tecla_4,
"tecla_5_clicked" : self.botao_tecla_5,
"tecla_6_clicked" : self.botao_tecla_6,
"tecla_7_clicked" : self.botao_tecla_7,
"tecla_8_clicked" : self.botao_tecla_8,
"tecla_9_clicked" : self.botao_tecla_9,
"tecla_0_clicked" : self.botao_tecla_0,
"tecla_backs_clicked" : self.botao_tecla_backs,
"tecla_ok_clicked" : self.botao_teclaok,
"tecla_21_clicked" : self.botao_tecla21,
"tecla_22_clicked" : self.botao_tecla22,
"tecla_23_clicked" : self.botao_tecla23,
"tecla_24_clicked" : self.botao_tecla24,
"tecla_25_clicked" : self.botao_tecla25,
"tecla_26_clicked" : self.botao_tecla26,
"tecla_27_clicked" : self.botao_tecla27,
"tecla_28_clicked" : self.botao_tecla28,
"tecla_29_clicked" : self.botao_tecla29,
"tecla_20_clicked" : self.botao_tecla20,
"tecla_backs2_clicked" : self.botao_teclabacks2,
"tecla_ok2_clicked" : self.botao_teclaok2
})
self.tempo_config_txt.set_text(str(self.tempo_set_valor))
self.pressao_set_config_txt.set_text(str(self.pressao_set_valor))
#FAZ LEITURA DO ARQUIVO DE CONFIGURAÇOES
if(self.flag_leitura_arquivo == 0 or flag_funcao == 10):
self.flag_leitura_arquivo = 1
try:
self.arquivo_config = open("data/config.dat", "r")
self.linha01 = self.arquivo_config.readline()
self.linha02 = self.arquivo_config.readline()
self.arquivo_config.close()
try:
self.linha01 = int(self.linha01)
except:
self.linha01 = 1
try:
self.linha02 = int(self.linha02)
except:
self.linha02 = 0
except:
print("*Erro ao ler arquivo config.dat")
try:
self.num_idioma = self.linha01
self.flag_volume_init = self.linha02
self.pressao_set_config_txt.set_text(str(self.linha03))
self.tempo_config_txt.set_text(str(self.linha04))
self.num_tempo = self.linha05
self.idioma_combobox.set_active((self.num_idioma-1))
self.tempo_combobox.set_active((self.num_tempo- 1 ))
self.tela_configuracao01(4, 1, self.flag_volume_init)
except:
print("*Erro nas conversões")
#ABRINDO A JANELA DE CONFIGURAÇÃO 01
self.janela_config01 = tela_configuracao01_builder.get_object("janela")
self.janela_config01.show()
# FLAG_FUNCAO 1 É PARA FECHAR A TELA E SALVAR AS CONFIGURAÇÕES SETADAS PELO USUÁRIO
elif(flag_funcao == 1):
#ABRE O ARQUIVO DE CONFIGURAÇÕES PARA SALVAR CONFIGURAÇÕES
try:
#FAZ LEITURA DAS POSIÇÕES DOS COMOBOX PARA ARMAZENAR
self.num_idioma = int(self.idioma_combobox.get_active_id())
self.num_tempo = int(self.tempo_combobox.get_active_id())
#ABRE ARQUIVO E SALVA INFORMAÇÕES
self.arquivo_config = open("data/config.dat", "w")
self.arquivo_config.write(str(self.num_idioma) + "\n")
self.arquivo_config.write(str(flag_volume) + "\n")
self.arquivo_config.write(str(self.pressao_set_config_txt.get_text()) + "\n")
self.arquivo_config.write(str(self.tempo_config_txt.get_text())+ "\n")
self.arquivo_config.write(str(self.num_tempo) + "\n")
self.arquivo_config.close()
except:
print("*Erro ao abrir arquivo config.dat")
#FECHA A JANELA DE CONFIGURAÇÃO
self.janela_config01.close()
# FLAG_FUNCAO 2 É QUANDO O COMBOBOX DE IDOMA É SELECIONADO, VERIFICA O IDIOMA E TRADUZ TELA
elif(flag_funcao == 2):
#FAZ LEITURA DA POSIÇÃO DO COMOBOBOX DE IDIOMA
self.num_idioma = int(self.idioma_combobox.get_active_id())
#FLAG FUNCAO 3 É QUANDO O COMBOBOX DA CONTAGEM DO TEMPO É SELECIONADO, FAZ LEITURA E SALVA
elif (flag_funcao == 3):
self.num_tempo = int(self.tempo_combobox.get_active_id())
#FLAG FUNCAO 4 NÃO FAZ NADA
elif(flag_funcao == 4):
pass
elif(flag_funcao == 5):
self.volume_tit_txt.set_visible(0)
self.imagem_fundo_config1.set_from_file("img_fundo_janela_principal2.png")
elif (flag_funcao == 6):
self.contador_teclado = self.contador_teclado + 1
if(self.contador_teclado == 1 and self.valor_teclado!=11):
self.pressao_set_valor = self.valor_teclado
elif(self.contador_teclado == 2 and self.valor_teclado!=11):
self.pressao_set_valor = (self.pressao_set_valor * 10)
self.pressao_set_valor = self.pressao_set_valor+ (self.valor_teclado)
elif(self.contador_teclado == 3 and self.valor_teclado!=11):
self.pressao_set_valor = self.pressao_set_valor * 10
self.pressao_set_valor = self.pressao_set_valor + (self.valor_teclado)
self.contador_teclado = 0
if(self.valor_teclado == 11):
self.contador_teclado = 0
self.valor_teclado = 0
self.pressao_set_valor = 0
self.imagem_fundo_config1.set_from_file("img_fundo_janela_principal.png")
elif (flag_funcao == 8):
self.titulo_txt.set_visible(0)
self.imagem_fundo_config1.set_from_file("img_fundo_janela_principal3.png")
elif (flag_funcao == 9):
self.contador_teclado2 = self.contador_teclado2 + 1
if(self.contador_teclado2 == 1 and self.valor_teclado!=11):
self.tempo_set_valor = self.valor_teclado
elif(self.contador_teclado2 == 2 and self.valor_teclado!=11):
self.tempo_set_valor = (self.tempo_set_valor * 10)
self.tempo_set_valor = self.tempo_set_valor+ (self.valor_teclado)
elif(self.contador_teclado2 == 3 and self.valor_teclado!=11):
self.tempo_set_valor = self.tempo_set_valor * 10
self.tempo_set_valor = self.tempo_set_valor + (self.valor_teclado)
self.contador_teclado2 = 0
if(self.valor_teclado==11):
self.contador_teclado = 0
self.valor_teclado = 0
self.tempo_set_valor = 0
self.tempo_config_txt.set_text(str(self.tempo_set_valor))
elif (flag_funcao == 11):
#BOTÕES E EVENTOS DA TELA DE CONFIGURAÇÃO 01
def desligaaa(self,widget):
Gtk.main_quit()
def botao_set_pressao(self, widget):
self.tela_configuracao01(5,0,0)
def botao_set_tempo(self, widget):
self.tela_configuracao01(8, 0, 0)
def botao_tecla_0(self, widget):
self.valor_teclado = 0
self.tela_configuracao01(6, 0, 0)
def botao_tecla_1(self, widget):
self.valor_teclado = 1
self.tela_configuracao01(6, 0, 0)
def botao_tecla_2(self, widget):
self.valor_teclado = 2
self.tela_configuracao01(6, 0, 0)
def botao_tecla_3(self, widget):
self.valor_teclado = 3
self.tela_configuracao01(6, 0, 0)
def botao_tecla_4(self, widget):
self.valor_teclado = 4
self.tela_configuracao01(6, 0, 0)
def botao_tecla_5(self, widget):
self.valor_teclado = 5
self.tela_configuracao01(6, 0, 0)
def botao_tecla_6(self, widget):
self.valor_teclado = 6
self.tela_configuracao01(6, 0, 0)
def botao_tecla_7(self, widget):
self.valor_teclado = 7
self.tela_configuracao01(6, 0, 0)
def botao_tecla_8(self, widget):
self.valor_teclado = 8
self.tela_configuracao01(6, 0, 0)
def botao_tecla_9(self, widget):
self.valor_teclado = 9
self.tela_configuracao01(6, 0, 0)
def botao_tecla_backs(self, widget):
self.valor_teclado = 11
self.tela_configuracao01(6, 0, 0)
def botao_teclaok (self, widget):
if (self.pressao_set_valor > self.pressao_max):
self.pressao_set_valor = self.pressao_max
elif (self.pressao_set_valor < self.pressao_min):
self.pressao_set_valor = self.pressao_min
self.pressao_set_config_txt.set_text(str(self.pressao_set_valor))
self.tela_configuracao01(7,0,0)
def botao_tecla20(self, widget):
self.valor_teclado = 0
self.tela_configuracao01(9, 0, 0)
def botao_tecla21(self, widget):
self.valor_teclado = 1
self.tela_configuracao01(9, 0, 0)
def botao_tecla22(self, widget):
self.valor_teclado = 2
self.tela_configuracao01(9, 0, 0)
def botao_tecla23(self, widget):
self.valor_teclado = 3
self.tela_configuracao01(9, 0, 0)
def botao_tecla24(self, widget):
self.valor_teclado = 4
self.tela_configuracao01(9, 0, 0)
def botao_tecla25(self, widget):
self.valor_teclado = 5
self.tela_configuracao01(9, 0, 0)
def botao_tecla26(self, widget):
self.valor_teclado = 6
self.tela_configuracao01(9, 0, 0)
def botao_tecla27(self, widget):
self.valor_teclado = 7
self.tela_configuracao01(9, 0, 0)
def botao_tecla28(self, widget):
self.valor_teclado = 8
self.tela_configuracao01(9, 0, 0)
def botao_tecla29(self, widget):
self.valor_teclado = 9
self.tela_configuracao01(9, 0, 0)
def botao_teclabacks2(self, widget):
self.valor_teclado = 11
self.tela_configuracao01(9, 0, 0)
def botao_teclaok2(self, widget):
if (self.tempo_set_valor > self.tempo_max):
self.tempo_set_valor = self.tempo_max
elif (self.tempo_set_valor < self.tempo_min):
self.tempo_set_valor = self.tempo_min
self.tempo_config_txt.set_text(str(self.tempo_set_valor))
self.tela_configuracao01(11, 0, 0)
########### TELA DE CONFIGURAÇÃO 02 ###########
def tela_configuracao02(self,flag):
if(flag == 0):
tela_config01_builder = Gtk.Builder()
tela_config01_builder.add_from_file("tela_inicial.glade")
#PEGANDO OBJETOS TXT
self.qwr_txt = tela_config01_builder.get_object("qwe_txt")
self.tourniquet_txt = tela_config01_builder.get_object("none_txt")
self.texto_inicial = tela_config01_buildeitr.get_object("texto_inicial_txt")
self.bemvindo_txt = tela_config01_builder.get_object("bemvindo_txt")
self.janela_config01 = tela_config01_builder.get_object("janela")
self.bemvindo_txt.set_text(" ")
def tela_teste01(self,flag):
if(flag == 0 or flag == 10):
tela_teste01_builder = Gtk.Builder()
tela_teste01_builder.add_from_file("tela_teste01.glade")
tela_teste01_builder.connect_signals({"ok01_bt_clicked" : self.botao_ok_teste02})
self.texto01_txt = tela_teste01_builder.get_object("texto01_txt")
self.erro_txt = tela_teste01_builder.get_object("erro_txt")
self.janela_teste01 = tela_teste01_builder.get_object("janela")
if (self.num_idioma == 1):
self.texto01_txt.set_text("Performing self test")
self.erro_txt.set_text("PULL THE SLEEVE, OK TO CONTINUE")
# 2 PORTUGUÊS
elif (self.num_idioma == 2):
self.texto01_txt.set_text("Realizando teste automático")
self.erro_txt.set_text("TIRE O MANGUITO, OK PARA CONTINUAR")
# ESPANHOL
elif (self.num_idioma == 3):
pass
self.janela_teste01.show()
else:
self.janela_teste01.close()
def botao_ok_teste02(self, widget):
self.flag_tela_teste01 = 1
self.tela_teste01(self.flag_tela_teste01)
self.flag_tela_teste02 = 0
self.tela_teste02(self.flag_tela_teste02)
def tela_teste02(self,flag):
if(flag == 0):
tela_teste02_builder = Gtk.Builder()
tela_teste02_builder.add_from_file("tela_teste02.glade")
tela_teste02_builder.connect_signals({"bt_avancar_clicked" : self.botao_avancar_teste02})
self.texto01_txt = tela_teste02_builder.get_object("texto01_txt")
self.erro_txt = tela_teste02_builder.get_object("erro_txt")
self.check_bt_txt = tela_teste02_builder.get_object("check_button_txt")
self.bt_avancar_txt = tela_teste02_builder.get_object("bt_avancar")
self.janela_teste02 = tela_teste02_builder.get_object("janela")
if (self.num_idioma == 1):
self.texto01_txt.set_text("Performing self test")
self.erro_txt.set_text("INFLATED SLEEVE :")
self.check_bt_txt.set_text("Depressurise")
self.bt_avancar_txt.set_label("Next")
# 2 PORTUGUÊS
elif (self.num_idioma == 2):
self.texto01_txt.set_text("Realizando teste automático")
self.erro_txt.set_text("MANGUITO INFLADO :")
self.check_bt_txt.set_text("Depressurizar")
self.bt_avancar_txt.set_label("Avançar")
# ESPANHOL
elif (self.num_idioma == 3):
pass
self.janela_teste02.show()
else:
self.janela_teste02.close()
def tela_principal(self,flag):
if(flag == 0 ):
# IMPORTANDO OBJETOS
tela_principal_builder = Gtk.Builder()
tela_principal_builder.add_from_file("tela_principal.glade")
self.janela_principal = tela_principal_builder.get_object("janela")
self.pressao01_txt = tela_principal_builder.get_object("pressao01_txt")
self.pressao02_txt = tela_principal_builder.get_object("pressao02_txt")
self.tempo01_txt = tela_principal_builder.get_object("tempo01_txt")
self.tempo02_txt = tela_principal_builder.get_object("tempo02_txt")
self.pressao01_tit_txt = tela_principal_builder.get_object("pressao01_tit_txt")
self.pressao02_tit_txt = tela_principal_builder.get_object("pressao02_tit_txt")
self.desinfla1_bt2_txt = tela_principal_builder.get_object("desinfla1_bt2_txt")
self.desinfla1_bt1_txt = tela_principal_builder.get_object("desinfla1_bt1_txt")
self.infla1_bt1_txt = tela_principal_builder.get_object("infla1_bt1_txt")
self.desinfla2_bt2_txt = tela_principal_builder.get_object("desinfla2_bt2_txt")
self.desinfla2_bt1_txt = tela_principal_builder.get_object("desinfla2_bt1_txt")
self.infla1_bt2_txt = tela_principal_builder.get_object("infla2_bt1_txt")
self.volume_icon_img = tela_principal_builder.get_object("volume_icon_img")
self.energia_icon_img = tela_principal_builder.get_object("energia_icon_img")
self.bateria_icon_img = tela_principal_builder.get_object("bateria_icon_img")
self.pressao01_barra = tela_principal_builder.get_object("valor_barra_pressao01")
self.pressao02_barra = tela_principal_builder.get_object("valor_barra_pressao02")
self.tempo01_barra = tela_principal_builder.get_object("valor_barra_tempo01")
self.tempo02_barra = tela_principal_builder.get_object("valor_barra_tempo02")
self.inflar01_bt01 = tela_principal_builder.get_object("infla1_bt1")
self.desinfla01_bt01 = tela_principal_builder.get_object("desinfla1_bt1")
self.desinfla01_bt02 = tela_principal_builder.get_object("desinfla1_bt2")
self.inflar02_bt01 = tela_principal_builder.get_object("infla2_bt1")
self.desinfla02_bt01 = tela_principal_builder.get_object("desinfla2_bt1")
self.desinfla02_bt02 = tela_principal_builder.get_object("desinfla2_bt2")
# CONECTANDO OS SINAIS DA TELA PRINCIPAL
tela_principal_builder.connect_signals({"pressao1_bt_mais_clicked" : self.botao_mais_pressao01,
"pressao1_bt_menos_clicked" : self.botao_menos_pressao01,
"tempo1_bt_mais_clicked" : self.botao_mais_tempo01,
"tempo1_bt_menos_clicked" : self.botao_menos_tempo01,
"pressao2_bt_mais_clicked" : self.botao_mais_pressao02,
"pressao2_bt_menos_clicked" : self.botao_menos_pressao02,
"tempo2_bt_mais_clicked" : self.botao_mais_tempo02,
"tempo2_bt_menos_clicked" : self.botao_menos_tempo02,
"volume_bt_clicked" : self.botao_volume,
"infla1_bt1_clicked" : self.botao_inflar01,
"pressao01_barra_value_changed" : self.barra_pressao01,
"pressao02_barra_value_changed" : self.barra_pressao02,
"tempo01_barra_value_changed" : self.barra_tempo01,
"tempo02_barra_value_changed" : self.barra_tempo02,
"energia_icon_img_destroy" : self.fechar_programa,
"bt_config_clicked" : self.botao_configuracao,
"bt_teste_clicked" : self.botao_realiza_teste,
"desinfla1_bt1_clicked" : self.botao1_desinfla1,
"desinfla1_bt2_clicked" : self.botao2_desinfla1,
"desinfla2_bt1_clicked" : self.botao1_desinfla2,
"desinfla2_bt2_clicked" : self.botao2_desinfla2,
"infla2_bt1_clicked" : self.botao1_infla2,
})
self.janela_principal.show()
# VARIAVEIS DA CLASSE
self.pressao01_set = 0
self.pressao02_set = 0
self.tempo01_set = 0
self.tempo02_set = 0
self.volume_cont = 3
# LENDO ARQUIVOS PARA VALORES INICIAIS
try:
self.Arquivo = open("data/pressao01_set.dat", "r")
self.pressao01_set = int(self.Arquivo.readline())
self.Arquivo.close()
except:
self.pressao01_set = 300
try:
self.Arquivo = open("data/pressao02_set.dat", "r")
self.pressao02_set = int(self.Arquivo.readline())
self.Arquivo.close()
except:
self.pressao02_set = 300
try:
self.Arquivo = open("data/tempo01_set.dat", "r")
self.tempo01_set = int(self.Arquivo.readline())
self.Arquivo.close()
except:
self.tempo01_set = 60
try:
self.Arquivo = open("data/tempo02_set.dat", "r")
self.tempo02_set = int(self.Arquivo.readline())
self.Arquivo.close()
except:
self.tempo02_set = 60
# MUDANDO A POSIÇÃO DAS BARRAS DE ACORDO COM O VALOR SETADO
self.pressao01_barra.set_value(self.pressao01_set)
self.pressao02_barra.set_value(self.pressao02_set)
self.tempo01_barra.set_value(self.tempo01_set)
self.tempo02_barra.set_value(self.tempo02_set)
# ESCREVENDO NA TELA OS VALORES INICIAS LIDOS NOS ARQUIVOS
self.pressao01_txt.set_text(str(self.pressao01_set))
self.pressao02_txt.set_text(str(self.pressao02_set))
self.tempo01_txt.set_text(str(self.tempo01_set))
self.tempo02_txt.set_text(str(self.tempo02_set))
else:
self.janela_principal.close()
def botao_configuracao(self, widget):
self.tela_principal(1)
self.flag_tela_config01 = 10
self.tela_configuracao01(self.flag_tela_config01,0,0)
def botao_realiza_teste(self,widget):
self.timer_tela_teste03 = 0
self.timer_tela_teste04 = 0
self.flag_tela_teste01 = 0
self.tela_teste01(self.flag_tela_teste01)
self.flag_tela_principal = 1
self.tela_principal(self.flag_tela_principal)
def fechar_programa(self, widget):
Gtk.main_quit()
#EVENTO DOS BOTÕES DA TELA PRINCIPAL
# Initialize Timer
def timer_tela_inicio(self):
# this takes 2 args: (how often to update in millisec, the method to run)
GObject.timeout_add(1000, self.func_tela_inicio)
def teste(self):
# this takes 2 args: (how often to update in millisec, the method to run)
GObject.timeout_add(1000, self.daprint)
def daprint(self):
self.teste()
print("timerzeira")
def InitProg (): Gtk.main ()
def InitCom (): Test = Modulo_Serial.Comunicacao () Test.SerialInit ("/ dev / ttyUSB1", 115200,1,1,)
vetor = [0, 20, 47, 10, 100, 100, 6, 7, 8, 9, 0, 10, 11, 23]
dadosrec = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
# print(vetor)
Teste.PreparaBufferTx(vetor)
# print(vetor)
Teste.EscritaSerial(vetor)
# print(dadosrec)
Teste.Leitura_Serial(dadosrec)
# print(dadosrec)
App = App ()
App.timer_tela_inicio () App.test ()
App.screen_installation (App.flag_screen_initial)
Init = multiprocessing.Process (name="InitProg", target = InitProg)
Init2 = multiprocessing.Process (name="InitProg", target = InitCom)
Init.run ()
Init2.run ()
DataRx, DataTx = Pipe ()
t = threading.Thread (target = InitCom) t2 = threading.Thread (target = InitProg) t.start () t2.start () t.join () t2.join ()