10

I have a code where I'm trying out different Tkinter widgets, but Colab sends back an error saying that there's no display name or variable. The exact error message looks something like what follows:

TclError                                  Traceback (most recent call last)
<ipython-input-5-7b43f8be599d> in <module>()
----> 1 form = tk.Tk()
   /usr/lib/python3.6/tkinter/__init__.py in __init__(self, screenName, baseName, className, useTk, sync, use)
   2021                 baseName = baseName + ext
   2022         interactive = 0
-> 2023         self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
   2024         if useTk:
   2025             self._loadtk()
TclError: no display name and no $DISPLAY environment variable

Is there any way to work around this? The code goes something like this:

import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
from tkinter import filedialog
def fOpen(): 
    print(filedialog.askopenfilename(initialdir = "/",title = "Open file",filetypes = (("Python files","*.py;*.pyw"),("All files","*.*"))))
def ExitF(): 
    form.destroy()
def fSave(): 
    print(filedialog.asksaveasfilename(initialdir = "/",title = "Save as",filetypes = (("Python files","*.py;*.pyw"),("All files","*.*"))))
form = tk.Tk()
form.title("Colab Form")
menubar = tk.Menu(form)
filemenu = tk.Menu(menubar,tearoff=0)
filemenu.add_command(label="Open", command = fOpen)
filemenu.add_command(label="Save", command = fSave)
filemenu.add_command(label="Exit", command = ExitF)
menubar.add_cascade(label="File", menu=filemenu)
form.config(menu=menubar)
#Listbox with attached scrollbar
scrollbar=tk.Scrollbar(form)
mylist = tk.Listbox(form, yscrollcommand = scrollbar.set )
for line in range(100):
   mylist.insert("end", "This is line number " + str(line))
mylist.grid(row=7,column=1,rowspan=3, sticky='e', padx=25, pady=25)
scrollbar.config( command = mylist.yview )
scrollbar.grid(row=7, column=2, rowspan=3, sticky='nsw', padx=25, pady=25)
form.mainloop()
AJ2599
  • 138
  • 1
  • 1
  • 10

2 Answers2

7

As Run gym-gazebo on Google Colaboratory says, you need to run a framebuffer server (that will emulate a graphical screen) and create a DISPLAY envvar pointing to it.

!apt-get install -y xvfb # Install X Virtual Frame Buffer
import os
os.system('Xvfb :1 -screen 0 1600x1200x16  &')    # create virtual display with size 1600x1200 and 16 bit color. Color can be changed to 24 or 8
os.environ['DISPLAY']=':1.0'    # tell X clients to use our virtual DISPLAY :1.0

However, if you want to interact with the GUI, that's going to be hard, 'cuz Colab doesn't support interactive screens out of the box.

ivan_pozdeev
  • 31,209
  • 16
  • 94
  • 140
  • I'm a little new to this, could you please elaborate a little on 'interact'? Also, please explain what I can and cannot use from Tkinter while on Colab? – AJ2599 Aug 16 '20 at 07:11
  • Intreract means UI automation from other processes: read info from windows, press buttons automatically etc. You can do that from the current process though. "What I can and cannot use from TKinter" -- not sure what you mean. With a framebuffer, all TKinter's API will work just like locally. – ivan_pozdeev Aug 16 '20 at 10:43
  • ...The only difference is that the graphical output will be to some virtual screen that you can't see or interact with directly. – ivan_pozdeev Aug 16 '20 at 10:46
7

No.

From the intro to google colab:

Colab notebooks execute code on Google's cloud servers

Servers generally don't even have a display. And even if they had, you wouldn't see it. You will have to run Python on your desktop or laptop to use tkinter.

Additionally, the colab environment is a form of IPython notebook, which is not really a standard Python environment. I would not recommend trying to run tkinter programs from an IPython notebook even if you have IPython running locally.

Roland Smith
  • 39,308
  • 3
  • 57
  • 86