17

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
  • 308
  • 1
  • 3
  • 10

2 Answers2

9

Yes, you can get it to run, but without seeing the graphical screen. (And triggering blind mouse/keyboard events programatically might be hard.)

As Run gym-gazebo on Google Colaboratory says, you can install and run a framebuffer Xserver (that will emulate a graphical screen).

Add the following lines at the beginning of your code cell to do that and set the DISPLAY environment variable as well:

!apt-get install -y xvfb # Install X Virtual Frame Buffer
import os
os.system('Xvfb :1 -screen 0 1600x1200x16  &')  # start it
os.environ['DISPLAY']=':1.0'  # tells X clients where to connect to
Robert Siemer
  • 32,405
  • 11
  • 84
  • 94
ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152
  • 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
9

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
  • 42,427
  • 3
  • 64
  • 94