1

I am implementing a clipboard monitor in my python app. If the copied text meets certain requirements, i want to show the user a dialog. if the user clicks "Yes" i'd like to trigger a function - in this case webui.app.add_internal(cb) . If the user chooses "No" i'd like to just keep checking the clipboard for changes on 3 seconds intervals.

Everything seems to be working fine, but this code does not run repeatedly nonstop like I expect. investigating it a little shows that Tk().withdraw() seems to be the problematic line. Although without it the main blank window of Tk will appear next to the dialog shown, and the last choice of the user seems to be remembered for later (which isn't desired).

Consider the following code:

import pyperclip
import tkMessageBox, Tkinter
import threading

cbOld = "notAurl"
def catchClipboardChange():
global cbOld
cb = pyperclip.paste()
Tkinter.Tk().withdraw()
if (cb != cbOld):
    #Change in clipboard detected. Analize!
    if (urlValidation(cb) and isDownloadExt(cb) and tkMessageBox.askyesno("Start downloading?","Do you want to start downloading {}".format(cb))):
        webui.app.add_internal(cb)
    cbOld = cb # Old clipboard update
threading.Timer(3.0,catchClipboardChange).start()

catchClipboardChange();

Any suggestions how this can be done better? I was thinking either about how to show a dialog without the need for the withdraw methods, or safer ways to use it with threading. Appriciate any help

user1555863
  • 2,567
  • 6
  • 35
  • 50

1 Answers1

2

No, you cannot call withdraw() from another thread other than the main thread.

Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
  • why is that? So how would you suggest going about this? – user1555863 May 06 '13 at 12:48
  • 1
    @user1555863: why is it? That's just the way it was designed; you can only call functions of a widget in the same thread that it was created. You need to set up a thread safe queue where you can post requests for the main thread, then poll the queue from the main thread and do the requests. – Bryan Oakley May 06 '13 at 13:05
  • Thanks. Can you provide an example of how this is done somewhere? – user1555863 May 06 '13 at 13:50
  • 1
    @user1555863: there are several examples on this site, just do a little searching. Here's one answer that uses Tkinter and a queue, though for a different purpose: http://stackoverflow.com/a/14381671/7432 – Bryan Oakley May 06 '13 at 14:35