Tkinter versus X-server : um erro de conexão em uma aplicação que não está na nuvem e nem faz nenhum

1. Tkinter versus X-server : um erro de conexão em uma aplicação que não está na nuvem e nem faz nenhum

Bartolomeu Silva
nao_eh_osimpson

(usa Linux Mint)

Enviado em 26/08/2021 - 16:23h

Hey hey hey camaradas,

Estou tendo um problema estranho com a biblioteca Tkinter do Python.... Ao chamar a função Tk() para criar a instância do tkinter, retorna-se um erro. No começo achei q era só algum erro bobo de síntaxe(e talvez seja mesmo), porém já procurei em alguns sites e fóruns e vi que parece um problema com a conexão com um server ou uma VM(máquina virtual)... Mas eu estou usando a minha máquina mesmo....
No protocol specified
No protocol specified
Traceback (most recent call last):
File "./rh.py", line 4, in <module>
menu=Menu(["Roboto",10],"LavenderBlush",[10,40],"250x140","MENU")
File "/home/bart/Documentos/projetos/Python/RH/janela.py", line 25, in __init__
super().__init__(fonte,fundo,titulo,tela)
File "/home/bart/Documentos/projetos/Python/RH/janela.py", line 10, in __init__
self.root = Tk()
File "/usr/lib/python3.6/tkinter/__init__.py", line 2023, in __init__
self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: couldn't connect to display ":0"




Encontrei a seguinte definição do erro e pq ele ocorre no fórum neurostarts(https://neurostars.org/t/mriqc-v0-14-2-error/2646?u=oesteban): "The error occurs when python does not have access to an X server (graphical interface)" ou seja, "O erro ocorre quando o python não consegue acessar um server X(interface gráfica)". Também tem um site que está escrito em mandarim na maior parte, mas há uma parte em inglês(https://codeleading.com/article/51792646473/):"The problem is that you are using an interactive backend which is trying to create figure windows for you, which are failing because you have disconnected the x-server that was available when you started the simulations." Isso reforça a teoria de ser um problema de conexão... Mas conexão com oq? Eu estou com a aplicação na minha máquina e não estou fazendo nenhum request...

Encontrei o link de um fórum(https://stackoverflow.com/questions/43397162/show-matplotlib-plots-and-other-gui-in-ubuntu-wsl1-wsl2) que sugere utilizar o seguinte comando:
export DISPLAY=localhost:0.0 

Eu inseri no terminal(do Linux Mint) este comando e não mudou nada.... Na verdade mudou a última linha, agora está "localhost:0" ao invés de ":0", segue o erro na íntegra
Traceback (most recent call last):
File "./rh.py", line 4, in <module>
menu=Menu(["Roboto",10],"LavenderBlush",[10,40],"250x140","MENU")
File "/home/bart/Documentos/projetos/Python/RH/janela.py", line 25, in __init__
super().__init__(fonte,fundo,titulo,tela)
File "/home/bart/Documentos/projetos/Python/RH/janela.py", line 10, in __init__
self.root = Tk()
File "/usr/lib/python3.6/tkinter/__init__.py", line 2023, in __init__
self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: couldn't connect to display "localhost:0.0"


Segundo este fórum(https://askubuntu.com/questions/7881/what-is-the-x-server), o X-server seria a aplicação que controla as janelas no Windows... Isso mostra que esse é um outro tipo de erro... Mas qual? Se for apenas uma coincidência ter dois fóruns falando X server, o outro lá pode estar falando X server com o intruito de colocar esse x como um nome aleatório do server.... Não sei mais o que pensar... O que devo fazer?

Sites em que procurei informações:
https://www.thecodingforums.com/threads/tkinter-problem-tclerror-couldnt-connect-to-display-0.967467...
https://stackoverflow.com/questions/39445047/python-tkinter-in-docker-tclerror-couldnt-connect-to-di...
https://github.com/poldracklab/mriqc/issues/758 (Esse fórum ainda está aberto para discussão... Parece que n sou o único com problemas...)
https://stackoverflow.com/questions/43397162/show-matplotlib-plots-and-other-gui-in-ubuntu-wsl1-wsl2

Minha aplicação:
rh.py:
#!/usr/bin/python3
from janela import *

menu=Menu(["Roboto",10],"LavenderBlush",[10,40],"250x140","MENU")
menu.root.mainloop()
#logar=Autenticar(["Roboto",10],"LavenderBlush",[1,40],('250x170'),"AUTENTICAR")

janela.py:
#!/usr/bin/python3
from tkinter import *
from tkinter import ttk
from criar_widgets import *
from banco import *

class Janelas:
def __init__(self,fonte,fundo,titulo,tela):
#Esta é a variável da janela mãe
self.root = Tk()

#Esta é a cor de fundo da janela
self.root["bg"]=fundo

#Este é o título
self.root.title(titulo)
#self.root.wm_title(titulo)
#self.titulo=Criar_Label_Titulo(self.root,titulo,fonte,fundo)

#Este é o tamanho da janela
self.root.geometry(tela)

class Menu(Janelas):
def __init__(self,fonte,fundo,xy,tela,titulo):
super().__init__(fonte,fundo,titulo,tela)

abaixar,alinhar=30,70

#logo=Image.open("logotipo.png")
#logotipo = ImageTk.PhotoImage(logo)


self.bt_login=Criar_Button(self.root,"AUTENTICAR",fonte,fundo,lambda:Autenticar(self.root, fonte, fundo, xy,"260x190","AUTENTICAR"),xy[0]+alinhar-5,xy[1]-10)

self.bt_cadastrar=Criar_Button(self.root,"CADASTRO",fonte,fundo,lambda:Cadastrar(self.root,fonte, fundo,xy,"510x410","CADASTRO"),xy[0]+alinhar,xy[1]+abaixar+5)

class Autenticar(Janelas):
def __init__(self,janela_antiga,fonte,fundo,xy,tela,titulo):

janela_antiga.destroy()

super().__init__(fonte,fundo,titulo,tela)

abaixar,alinhar=30,70

#self.title("Autenticar")
self.var=StringVar()

self.rg=Criar_RadioButton(self.root,fonte,fundo,"RG",xy[0]+alinhar,5,self.var,"rg")
self.cpf=Criar_RadioButton(self.root,fonte,fundo,"CPF",xy[0],5,self.var,"cpf")
self.escolha=Criar_Button(
self.root,
"Escolher",
fonte,
fundo,
lambda:self.escolher_id(
xy,
abaixar,
alinhar,
fonte,
fundo
),
xy[0]+alinhar*2,
5
)

self.orientar=Criar_Label(self.root,"ESCOLHA CPF OU RG",xy[0],xy[1]+abaixar,['Roboto',15],fundo)

#Este é o tamanho da janela
self.root.mainloop()

def escolher_id(self,xy,abaixar,alinhar,fonte,fundo):
self.orientar.label.destroy()

self.usuario=Criar_Label(self.root,self.var.get().upper(),xy[0],xy[1]+abaixar,fonte,fundo)
self.entrar_usuario=Criar_Entry(self.root,xy[0]+alinhar,xy[1]+abaixar,fonte,False)

#Label e entrada da senha respectivamente
self.senha=Criar_Label(self.root,"SENHA",xy[0],xy[1]+abaixar*2,fonte,fundo)
self.entrar_senha=Criar_Entry(self.root,xy[0]+alinhar,xy[1]+abaixar*2,fonte,True)

#Botão que fará a mudança para uma nova tela
self.botao=Criar_Button(
self.root,
"AUTENTICAR",
fonte,
fundo,
lambda:self.autenticar(fonte,fundo,xy),
xy[0],
xy[1]+abaixar*3)

def autenticar(self,fonte,fundo,xy):
banco=Banco()
if self.var.get()=="cpf" or self.var.get()=="rg":
print("cpf = '"+self.entrar_usuario.entry.get()+"'")
banco.resultado = banco.mostrar(self.var.get()+",senha","Funcionario",self.var.get()+" = '"+self.entrar_usuario.entry.get()+"'")
if (self.entrar_usuario.entry.get() == str(banco.resultado[0][0]) and self.entrar_senha.entry.get() == banco.resultado[0][1]):
print("Você logou")
menu_logado=Menu2(self.root,fonte,fundo,xy,"260x190","MENU")
else:
print("Usuário ou senha inválidos\nUsuario inserido:"+self.entrar_usuario.entry.get()+" Senha inserida:"+self.entrar_senha.entry.get()+"\nUsuario do banco:"+banco.resultado[0][0]+" Senha do banco:"+banco.resultado[0][1])

class Cadastrar(Janelas):
def __init__(self,janela_antiga,fonte,fundo,xy,tela,titulo):
#Adeus janela antiga
janela_antiga.destroy()

#olá janela nova
super().__init__(fonte,fundo,titulo,tela)

#As variáveis a seguir serão usadas para alinhar e abaixar cada widget
abaixar,alinhar=30,150

#Label e entrada do nome
self.nome=Criar_Label(self.root,"NOME",xy[0],xy[1],fonte,fundo)
self.entrar_nome=Criar_Entry(self.root,xy[0]+alinhar,xy[1],fonte,False)

#Label e entrada do CPF
self.cpf=Criar_Label(self.root,"CPF",xy[0],xy[1]+abaixar,fonte,fundo)
self.entrar_cpf=Criar_Entry(self.root,xy[0]+alinhar,xy[1]+abaixar,fonte,False)

#Label e entrada do RG
self.rg=Criar_Label(self.root,"RG",xy[0],xy[1]+2*abaixar,fonte,fundo)
self.entrar_rg=Criar_Entry(self.root,xy[0]+alinhar,xy[1]+2*abaixar,fonte,False)

#Label e entrada do senha
self.senha=Criar_Label(self.root,"SENHA",xy[0],xy[1]+3*abaixar,fonte,fundo)
self.entrar_senha=Criar_Entry(self.root,xy[0]+alinhar,xy[1]+3*abaixar,fonte,True)

#Label e entrada do E-mail
self.email=Criar_Label(self.root,"E-mail",xy[0],xy[1]+4*abaixar,fonte,fundo)
self.entrar_email=Criar_Entry(self.root,xy[0]+alinhar,xy[1]+4*abaixar,fonte,False)

#Label e entrada do cargo
self.cargo=Criar_Label(self.root,"CARGO",xy[0],xy[1]+5*abaixar,fonte,fundo)
self.entrar_cargo=Criar_Entry(self.root,xy[0]+alinhar,xy[1]+5*abaixar,fonte,False)

#Label e entrada da formação
self.formacao=Criar_Label(self.root,"FORMAÇÃO",xy[0],xy[1]+6*abaixar,fonte,fundo)
self.entrar_formacao=Criar_Entry(self.root,xy[0]+alinhar,xy[1]+6*abaixar,fonte,False)

#Label e entrada do salário inicial
self.sal_in=Criar_Label(self.root,"SALÁRIO INICIAL",xy[0],xy[1]+7*abaixar,fonte,fundo)
self.entrar_sal_in=Criar_Entry(self.root,xy[0]+alinhar,xy[1]+7*abaixar,fonte,False)

#Botão para cadastrar
self.botao_cadastrar=Criar_Button(
self.root,
"CADASTRAR",
fonte,
fundo,
lambda:self.salvar(
(
self.entrar_cpf.entry.get(),
self.entrar_rg.entry.get(),
self.entrar_senha.entry.get(),
self.entrar_email.entry.get(),
self.entrar_cargo.entry.get(),
self.entrar_formacao.entry.get(),
self.entrar_nome.entry.get(),
self.entrar_sal_in.entry.get()
),
fonte,
fundo,
xy
),
xy[0]+alinhar,
xy[1]+8*abaixar
)

self.root.mainloop()

def salvar(self,dados,fonte,fundo,xy):
#Conexão com o banco
banco=Banco()
#Inserir dados no banco
banco.inserir("INSERT INTO Funcionario(cpf,rg,senha,email,cargo,formacao,nome,salario_inicial) VALUES(%s,%s,%s,%s,%s,%s,%s,%s);",dados)
#Desconectando
banco.desconectar()

logar = Autenticar(self.root,fonte,fundo,xy,"260x190","AUTENTICAR")


class Menu2(Janelas):
def __init__(self,janela_antiga,fonte,fundo,xy,tela,titulo):

#Adeus janela antiga
janela_antiga.destroy()

super().__init__(fonte,fundo,titulo,tela)

abaixar,alinhar=30,70

#logo=Image.open("logotipo.png")
#logotipo = ImageTk.PhotoImage(logo)

#Criando o título da Janela
labelTitulo=Criar_Label_Titulo(self.root,"MENU",fonte,fundo)

#Aqui está o botão para a janela de Projetos
self.bt_proj=Criar_Button(
self.root,
"PROJETOS",
fonte,
fundo,
lambda:Projetos(
self.root,
fonte,
fundo,
xy,
"260x190",
"PROJETOS"
),
xy[0]+alinhar-5,
xy[1]-10
)

#self.bt_cadastrar=Criar_Button(self.root,"CADASTRO",fonte,fundo,lambda:Cadastrar(self.root,fonte, fundo,xy,"510x410","CADASTRO"),xy[0]+alinhar,xy[1]+abaixar+5)

class Projetos(Janelas):
def __init__(self,janela_antiga,fonte,fundo,xy,tela,titulo):
#Adeus janela antiga
janela_antiga.destroy()

#olá janela nova
super().__init__(fonte,fundo,titulo,tela)

#Aqui está sendo colocado o título
labelTitulo=Criar_Label_Titulo(self.root,"PROJETOS",fonte,fundo)

#Aqui está o spinbox
lista_campos=Criar_Spinbox(self.root,fonte,xy[0],xy[1],['ID','NOME DO PROJETO','INTEGRANTE','PRAZO','ORÇAMENTO'])

#Aqui está a entrada para
entrar_valor=Criar_Entry(self.root,xy[0]+20,xy[1],fonte,False)

#Aqui está o botão para submeter
bt_confirmar=Criar_Button(
self.root,
"CONFIRMAR",
fonte,
fundo,
lambda:Projetos.buscar_projeto(),
xy[0]+40,
xy[1]
)
def buscar_projeto(self):
banco==Banco()
__resultado=banco.mostrar()
#__resultado
self.mostrar_resultado=Criar_Tabela(root,(1,2,3,4),('ID','NOME DO PROJETO','INTEGRANTE','PRAZO','ORÇAMENTO'))
self.mostrar_resultado.tabela.insert()
print(__resultado)
#self.chat1.insert()

criar_widgets.py
#!/usr/bin/python3
#!/bin/python3
from tkinter import *
from tkinter import ttk

class Criar_Label:
def __init__(self,root,texto,abcissa,ordenada,fonte,fundo):
self.label=Label(root)
self.label["text"]=texto
self.label["font"]=fonte
self.label["bg"]=fundo
self.label.place(x=abcissa,y=ordenada)

#Será que deveríamos fazer polimorfismo aqui e fazer da classe Criar_Label a classe mãe?
class Criar_Label_Titulo:
def __init__(self,root,texto,fonte,fundo):
self.titulo=Label(root)
self.titulo["text"]=texto
self.titulo["font"]=fonte
self.titulo["bg"]=fundo
self.titulo.pack()

class Criar_Entry:
def __init__(self,root,abcissa,ordenada,fonte,segredo):
self.entry=Entry(root,font=fonte)
self.entry.place(x=abcissa,y=ordenada)
if segredo:
self.entry["show"]="*"

class Criar_Button:
def __init__(self,root,texto,fonte,fundo,comando,abcissa,ordenada):
self.button=Button(root)
self.button["text"]=texto
self.button["font"]=fonte
self.button["bg"]=fundo
self.button["command"]=comando
self.button.place(x=abcissa,y=ordenada)

class Criar_RadioButton:
def __init__(self,root,fonte,fundo,texto,abcissa,ordenada,var,identificador):

self.radiobutton=Radiobutton(root)
self.radiobutton["font"]=fonte
self.radiobutton["bg"]=fundo
self.radiobutton["text"]=texto
self.radiobutton["value"]=identificador
self.radiobutton["variable"]=var

self.radiobutton.place(x=abcissa,y=ordenada)

class Criar_Spinbox:
def __init__(self,root,origem,fim,abcissa,ordenada,largura):
self.spinbox=Spinbox(root,from_=origem,to=fim,width=largura)
self.spinbox.place(x=abcissa,y=ordenada)

class Criar_Listbox:
def __init__(root,fonte,abcissa,ordenada,lista):
self.listbox=Listbox(root,fonte,abcissa,ordenada)
for i in lista:
self.listbox.insert(lista[i])
self.listbox.yview()
self.place(x=abcissa,y=ordenada)

class Criar_Tabela():
def __init__(self,root,conteudo,n_colunas,colunas):
self.tabela=ttk.Treeview(root,columns=n_colunas,show="headings",height="60")
for i in n_colunas:
self.tabela.heading(i, colunas[i-1])



  


2. Era só fechar o terminal e abrir denovo

Bartolomeu Silva
nao_eh_osimpson

(usa Linux Mint)

Enviado em 26/08/2021 - 17:51h


Hey hey hey camaradas,
Como mencionei acima, um dos fóruns mencionava a variável global $DISPLAY, assim me perguntei oq exatamente seria essa variável... Achei um site(https://anargodjaev.wordpress.com/2020/05/06/how-to-set-display-variable-in-linux/) dizendo o seguinte:
Whenever you want to invoke graphical interface in Linux, You must know how to set DISPLAY variable in order to open the GUI.Linux by default does
not allow you to open any GUI (Linux Oracle Installer) until you enable the GUI display.

Em português:
Sempre que você quiser invocar uma interface gráfica no Linux, você deve saber como configurar a variável DISPLAY em ordem para abrir o GUI.O linux, por padrão, não permite que vc abra qualquer GUI(Instalador Linux do Oracle) até vc habilitar o GUI display

Apesar de um pouco confuso, eu entendi a ideia do texto: vc não consegue alterar esse GUI até vc configurar a variável global DISPLAY, logo parece que não é algo que nós fazemos sempre... Se não fazemos sempre, então o problema não é algo que eu fiz de errado para desconfigurar... Logo pensei: "É só fechar e abrir denovo" e deu certo... Às vezes eu não entendo esses problemas aleatórios que dão no sistema operacional....
+------+
| bart |
+------+






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts