1

I have been reluctant to ask this question - I have been trying to solve it and have looked everywhere!

So, I run a company where we have several third parties emailing us with notifications of sales - all to different addresses. Each email to us is exactly one sale. The issue is that nowhere in the office is it possible to see the current total of sales (submissions) for that moment. I have been dying to learn Python since I was young so I figured that I would find a cool way to graphically display a sort of ticker that has a big number on a screen that we can hang on a wall in the office for everyone to see, via a Raspberry Pi and an LCD. But my gawd is this tough to do.

Outside of Python, it's all good to go, I have figured out the emailing to one inbox and I have managed to set a timer on our Gmail to mark the reads after 24hrs. The problem I am having is that I really want the program to update its counting of the unreads in real-time automatically without scrolling forever down the screen.

I have looked everywhere, loops don't seem to refresh the number on the window, nothing works apart from restarting the program again which is not automated and requires myself to start the program again. So, please, any help on this would be great. I plan to add graphics later, and maybe a little sound that goes ping or CHaaaChing when a sale comes in, but I thought I'd get this hard stuff out of the way first.

Here is my code:

#! /usr/bin/env python3.4
import imaplib
import email

from tkinter import *
root = Tk()


def window(main):
    main.title('submissions counter')
    width = 500
    height = 500
    x = (main.winfo_screenwidth() //2 ) - (width // 2)
    y = (main.winfo_screenheight() //2 ) - (height // 2)
    main.geometry('{}x{}+{}+{}'.format(width, height, x, y))

mail=imaplib.IMAP4_SSL('imap.gmail.com',993)
mail.login('email@gmail.com','Password')
mail.select("Submissions")
typ, messageIDs = mail.search(None, "UNSEEN")
messageIDsString = str( messageIDs[0], encoding='utf8' )
listOfSplitStrings = messageIDsString.split(" ")

if len(listOfSplitStrings) == 0:
    print('no submissions')
elif len(listOfSplitStrings) == 1:
    print(len(listOfSplitStrings),'submission[s]')
else:
    print(len(listOfSplitStrings),'submission[s]')

def main_content():
    hello = Label(root, text=(len(listOfSplitStrings),'submission[s]'))
    hello.pack()

window(root)
main_content()
root.mainloop()

Now I am trying with this code and getting nothing from it at all, no error messages, no results on the text box or on the command line...

#! /usr/bin/env python3.4
import imaplib
import email
import tkinter as tk

WIDTH = 500
HEIGHT = 500


def update():
    mail=imaplib.IMAP4_SSL('imap.gmail.com',993)
    mail.login('email"gmail.com','password')
    mail.select("Submissions")
    typ, messageIDs = mail.search(None, "UNSEEN")
    messageIDsString = str( messageIDs[0], encoding='utf8' )
    listOfSplitStrings = messageIDsString.split(" ")

    number = len(listOfSplitStrings)

    if number == 0:
        info['text'] = 'no submissions'
    else:
        info['text'] = '{} submissions[s]'.format(number)

    root.after(5000, update)

root = tk.Tk()

root.title('submissions counter')

x = (root.winfo_screenwidth()//2) - (WIDTH//2)
y = (root.winfo_screenheight()//2) - (HEIGHT//2)
root.geometry('{}x{}+{}+{}'.format(WIDTH, HEIGHT, x, y))

info = tk.Label(root, text='no submissions')
info.pack

update()
root.mainloop()
Smokeyparkin
  • 103
  • 6
  • I suggest you take a look at [my answer](https://stackoverflow.com/a/18091356/355230) to another somewhat-related question. You should be able to use the `errorwindow.py` file in it for your purposes (because it has no dependencies on the referenced `easygui` module). – martineau Jan 16 '18 at 01:20
  • ity seems you have to use `root.after(milliseconds, function_name)` to execute function periodically and not block `mainloop()` – furas Jan 16 '18 at 08:14

1 Answers1

0

It seems you need root.after(milliseconds, function_name) to execute function periodically and not block mainloop() which redraws widgets in window.

I could look like this

#! /usr/bin/env python3.4
import imaplib
import email
import tkinter as tk
#import random # for test without using mail

# --- constants --- (UPPER_CASE_NAMES)

WIDTH = 500
HEIGHT = 500

# --- functions --- (lower_case_names)

def update():

    mail = imaplib.IMAP4_SSL('imap.gmail.com', 993)
    mail.login('email@gmail.com', 'Password')
    mail.select("Submissions")
    typ, messageIDs = mail.search(None, "UNSEEN")
    messageIDsString = str(messageIDs[0], encoding='utf8')
    listOfSplitStrings = messageIDsString.split(" ")

    number = len(listOfSplitStrings)    
    #number = random.randint(0, 5) # for test without using mail

    if number == 0:
        #print('no submissions')
        info['text'] = 'no submissions'
    else:
        #print(number, 'submission[s]')
        info['text'] = '{} submission[s]'.format(number)

    # update again after 5000ms (5seconds)
    root.after(5000, update)

# --- main --- (lower_case_names)

root = tk.Tk()

root.title('submissions counter')

x = (root.winfo_screenwidth()//2) - (WIDTH//2)
y = (root.winfo_screenheight()//2) - (HEIGHT//2)
root.geometry('{}x{}+{}+{}'.format(WIDTH, HEIGHT, x, y))

# create label for information
info = tk.Label(root, text='no submissions')
info.pack()

# update label first time
update()

root.mainloop()
furas
  • 134,197
  • 12
  • 106
  • 148
  • Hi thanks for this. I am sure it will help. The only issue I now having running the code is the message: .... line 28, in root = tk.Tk() NameError: name 'tk' is not defined – Smokeyparkin Jan 16 '18 at 11:49
  • I thought this was defined in the ' root = tk.Tk() ' part? – Smokeyparkin Jan 16 '18 at 11:52
  • 1
    I use `import tkinter as tk` and then I can use `tk.` instead of `tkinter.` - ie. `tk.Tk()` instead of `tkinter.Tk()` - and this is your problem in error message. If you use `from tkinter import *` (which is not prefered method) then you don't have `tk` – furas Jan 16 '18 at 11:54
  • Unless I am being completely stupid, which I probably am being, it isn't delivering the number nor the text in the box. I have literally replicated your code, and updated the import tkinter, still nothing shows up in the actual text box, what do you think I am doing wrong? Thanks again. – Smokeyparkin Jan 17 '18 at 14:47
  • first run in command line to see if you don't get error message. You can also use `print()` to see values in variables and which part of code is executed - it is called "print debugging". I can't say anything more without full code - and full error message (Traceback) - so you can create new question. – furas Jan 17 '18 at 19:44
  • No errors at all. I basically copied your code word for word and all I am getting is a blank command line and a blank text box. It would appear that the data is being collected, I checked using print debugging like you suggested (ty btw), and the 'number' is held in 'number', so it would seem that for some reason the lines for the if, else which begin with info['text'] = '{} submissions[s]'.format(number) is what appears to not be working. Is there another way? – Smokeyparkin Jan 18 '18 at 00:21
  • When I add the line... else: print(number) - with the correct indent it appears to deliver the correct number of submissions on to the command line, but not into the text box, that remains blank. – Smokeyparkin Jan 18 '18 at 00:32
  • Got it working, my bad on the info.pack, not putting in a () at the end. Soooo annoying, but thank you this now works great!!! – Smokeyparkin Jan 18 '18 at 13:35