There is no display name and $ DISPLAY variable for the environment using tkinter on raspberry Pi B + from the boot shell script

my first post, so apologize if i do something wrong.

I wrote a python script using tkinter in python3, which works fine with IDLE3. I wanted this script to run when I started Pi, so I followed the following procedure to run @reboot using the cron job. http://www.instructables.com/id/Raspberry-Pi-Launch-Python-script-on-startup/step4/Add-to-your-crontab/

I initially received an initialization error, so I added 120 /; to '/ bin / sleep;' to the @reboot line, so now it reads as follows and seems to wait long enough for everything to initialize after loading. @ reboot / bin / sleep 120; sh / home / pi / launcher.sh> / home / pi / logs / cronlog 2> & 1

But after that, my cronlog shows the following error:

Traceback (last last call): File "walk.py", line 29, in MyGUI = Tk () File "/usr/lib/python3.2/tkinter/ init .py", line 1701, in init self.tk = _tkinter.create (screenName, baseName, className, interactive, wantobjects, useTk, sync, use) _tkinter.TclError: there is no display name and there is no environment variable $ DISPLAY

Now I saw this error for other threads, and many seem to relate to initializing libraries that I don't use. I want to add that my code works different from downtime, different from the terminal, I made launcher.sh and made it executable, and if I ran "sh launcher.sh" from the terminal, it works fine, so the launcher.sh script looks like not bad. but when I download, I get the above error, and I have no idea why? Please, help.

I do not have a copy of the code on this computer, but I will try to copy it and send it as a comment if anyone thinks this will help.

Thanks in advance Paul

FULL CODE BELOW


import sys import tkinter #might not be needed from tkinter import * import pymysql import os.path import datetime import json #Define local database connection try: localdb = pymysql.connect(host="localhost", user="root", passwd="p054169q", db="walk") except Exception as e: sys.exit('Can not locate localdb') lcur = localdb.cursor() #Define web database connection (Maybe add later for easy sync) #Initialise GUI using Tkinter MyGUI = Tk() #Remove title bar from GUI window #(BUG: Causes window not to have focus for scanning) #MyGUI.overrideredirect(1) #Doing it this way works but disable until working on small screen, this just sets window as fullscreen #MyGUI.attributes('-fullscreen', True) #Set window to resolution of screen 800x420 pixels MyGUI.geometry('800x420') #Set window title (Perhaps later remove title bar if possible) MyGUI.title('Island Walk Tracker') #Set window background colour to black MyGUI.configure(background='black') ##GLOBAL VARIABLES ## #Create variable for RFID code global RFIDcode RFIDcode = '' #Create variable for checkpoint number global checkpoint_number checkpoint_number = 2 #Create variable for photo filepath global photo_path photo_path = '' ## DECLARE ALL TKINTER VARIABLES ## #Declare like this for a tkinter variable to update dynamically on GUI (A global var will not do this) rfid_codeTK = StringVar() rfid_codeTK.set('') walk_numberTK = IntVar() walk_numberTK.set(0) fullnameTK = StringVar() fullnameTK.set('') classTK = StringVar() classTK.set('') ## DEFINE LABELS AND HOW/WHERE THEY APPEAR ON THE SCREEN ## #USE 'textvariable' instead of text for labels below to link to a live variable (See info here http://www.tutorialspoint.com/python/tk_label.htm) #Spacer label just adds blank label of fixed width to set width of column and space down one row from top of page lblSpacer = Label (text = ' ',fg='white',bg='black',font = 'Helvetica 8 bold') lblSpacer.grid(row=0,column=0) #TEST CODE: Display variable RFIDcode in a label for testing. Comment out to hide rfid code. #lblRFID = Label (MyGUI,textvariable = rfid_codeTK ,fg='white',bg='black',font = 'Helvetica 20 bold') #lblRFID.grid(row=3,column=1) #Display Walk number in a label lblWalkNumber = Label(MyGUI,textvariable = walk_numberTK ,fg='white',bg='black',font = 'Helvetica 115 bold') #Unlike other TK variables this is not placed in grid until after scan as this stops a big '0' appearing on screen #lblWalkNumber.grid(row=2,column=0) #Display Walker name in a label lblWalkerName = Label (MyGUI,textvariable = fullnameTK ,fg='white',bg='black',font = 'Helvetica 25 bold') lblWalkerName.grid(row=3,column=0) #Display class in a label lblWalkerClass = Label(MyGUI,textvariable = classTK ,fg='white',bg='black',font = 'Helvetica 25 bold') lblWalkerClass.grid(row=4,column=0) #Display photo on the screen #TEST CODE: later on change 'Blank' for the field in database that represents Student_ID #photo_path = 'WALK_PHOTOS/'+ 'Blank' +'.gif' #pic = PhotoImage(file= photo_path ) #ImgWalkerPhoto = Label(MyGUI,image = pic) #ImgWalkerPhoto.grid(row=2,column=1) ## EVENT OCCURS WHEN RFID CODE IS ENTERED (following 'enter' keypress) ## def Update_Walker_Screen(event): global RFIDcode global photo_path global checkpoint_number #Search database for matching RFIDcode from localdb and SELECT all data from that row lcur.execute("SELECT walk_number, forename, surname, class, student_id FROM walkers WHERE rfid_code = '"+ RFIDcode +"'") row = lcur.fetchall() ## SET POSITIONS OF THINGS ON THE TKINTER FORM ## #Display walker number in its label (done here after the scan event as if done above with other TK variables a big '0' appears on screen because it is an int so has a '0' not null value when initialised. lblWalkNumber.grid(row=2,column=0) pic = PhotoImage(file='WALK_PHOTOS/'+ 'Blank' +'.gif') ImgWalkerPhoto = Label(MyGUI,image = pic) #Hide image for testing #ImgWalkerPhoto.grid(row=2,column=1) ## SET VARIABLES TO DISPLAY ON SCREEN (WILL AUTO UPDATE SCREEN WHEN TK VARIABLES CHANGE) ## #Set rfid_codeTK variable to be RFIDcode from the code entered from scan. rfid_codeTK.set(RFIDcode) #Set walk_numberTK variable to be walk_number from the fetched database record walk_numberTK.set(row[0][0]) #Set fullnameTK variable to be forename + surname from the fetched database record fullnameTK.set(row[0][1] + ' ' + row[0][2]) #Set classTK variable to be class from the fetched database record classTK.set(row[0][3]) #Display photo on the screen after scan photo_path = 'WALK_PHOTOS/'+ row[0][4] +'.gif' if os.path.isfile(photo_path) == True: #show photo with filename as photo_path = 'WALK_PHOTOS/'+ row[0][4] +'.gif' else: #show blank photo photo_path = 'WALK_PHOTOS/Blank.gif' #Display image #ImgWalkerPhoto.grid(row=2,column=1) #This should update screen items (does flash picture up but not sure if its any use) #MyGUI.update_idletasks() #Look up current time walkers_time = datetime.datetime.now().strftime("%H:%M:%S") #Log time into database in correct checkpoint column if checkpoint_number == 1: #sqlquery = """INSERT INTO walkers('ckpt_1') VALUES({0})""".format(json.dumps(walkers_time)) #lcur.execute("INSERT INTO walkers('ckpt_1') VALUES () print('Checkpoint 1 selected') elif checkpoint_number == 2: sqlquery = "INSERT INTO walkers('ckpt_1') VALUES({0})".format(json.dumps(walkers_time)) print(sqlquery) print('Checkpoint 2 selected') elif checkpoint_number == 3: print('Checkpoint 3 selected') elif checkpoint_number == 4: print('Checkpoint 4 selected') elif checkpoint_number == 5: print('Checkpoint 5 selected') elif checkpoint_number == 6: print('Checkpoint 6 selected') elif checkpoint_number == 7: print('Checkpoint 7 selected') elif checkpoint_number == 8: print('Checkpoint 8 selected') elif checkpoint_number == 9: print('Checkpoint 9 selected') elif checkpoint_number == 10: print('Checkpoint 10 selected') elif checkpoint_number == 11: print('Checkpoint 11 selected') elif checkpoint_number == 12: print('Checkpoint 12 selected') else: #Checkpoint not correctly selected so ask them to restart and select a new checkpoint number print('Please select a checkpoint number') #Write the scanned walker details into text file ready to email. If file does not exist then create it, else append to existing file. #file = open('emaildata.txt', 'a') with open('emaildata.txt', 'a') as myfile: myfile.write(str(row[0][0]) + ',' + str(walkers_time) + ',' + 'Y' + '|')#walk_numberTK.get()) #Clear global variable RFIDcode ready for next scan. RFIDcode = '' #This function detects any keypresses and then adds them intothe RFIDcode global string variable #(Ignores Enter key as thats handled earlier in code so never reaches it. Add extra ignores if needed above.) def keypress(event): global RFIDcode RFIDcode = RFIDcode + str(event.char) #Bind any key press to run the keypress function. MyGUI.bind('<Key>',keypress) #Bind an 'Enter' key press to run the Update_Walker_Screen function. MyGUI.bind('<Return>',Update_Walker_Screen) MyGUI.mainloop() 
+6
source share
2 answers

I do not think that the problem with your code is causing your error. Especially since you said:

I want to add that my code works fine with downtime, different from the terminal

Let me assume that although cron is a great tool for scheduling repetitive tasks that I use all the time (every minute forever, actually), it may not be the best tool to meet your needs.

Since you want to run your program when loading PI, and your program runs in X , why don't you add it to the LXDE autorun file? Using nano or a text editor of your choice, edit the following file:
For older Raspbian builders:

 sudo nano /etc/xdg/lxsession/LXDE/autostart 

Or for the current Rasbian build:

 sudo nano /etc/xdg/lxsession/LXDE-pi/autostart 

Add the following line and save the file:

 @sh /home/pi/launcher.sh 

Or, if you also want a terminal window, for debugging:

 @lxterminal --command='sh /home/pi/launcher.sh' 

<h / "> In addition, you can make shell scripts and python scripts executable in two simple steps.

  • Add hashbang to the first line of the script.
    Python: #!/usr/bin/python2 or #!/usr/bin/python3


    Shell: #!/bin/sh #!/bin/bash
  • Mark the script as executable. At the command prompt, type:

    chmod +X ./myscript.sh or sudo chmod 755 ./myscript.sh

+2
source

Adam's answer is great, but a recent change in Raspian means you need to edit another LXDE-pi file:

sudo nano ~ / .config / lxsession / LXDE-pi / autostart

I did it, and now it works for me.

+1
source

Source: https://habr.com/ru/post/985866/


All Articles