Some description about the code:
- This is part of my program and I only put the related lines here
- What I hope these code could do,is to watch for my clipboard.If I copy "http:xxx" to my clipboard,it shows a pop-up window.If the content of the clipboard doesn't change,the window won't show again
- When running,it can pop up the window normally for one time,but won't do it again when I copy another string to clipboard starting with 'http:'
- I've tried some different interval values in the
after
method,same result.
Code:
from tkinter import *
import os
import tkinter.messagebox as messagebox
import threading
import re
def watch_clipboard(tk,pipeout):
content = ''
last_content = ''
while True:
try:
content = tk.clipboard_get()
except TclError:
pass
result = re.match('http:',content)
if content != last_content:
if result:
last_content = content
message = 'show'.encode()
os.write(pipeout,message)
class GUI:
def __init__(self):
self.tk = Tk()
self.tk.resizable(0, 0)
self.tk.title('watch clipboard')
pipein,pipeout = os.pipe()
threading.Thread(target=watch_clipboard,daemon=True,args=(self.tk,pipeout)).start()
self.tk.after(5000,lambda:self.clipboard_confirm(pipein))
self.tk.mainloop()
def clipboard_confirm(self,pipein):
message = os.read(pipein,16)
if message == b'show':
self.tk.clipboard_clear()
messagebox.askokcancel('', 'add this in?', default='ok')
self.tk.after(5000,clipboard_confirm(pipein)) #add this
if __name__ == '__main__':
gui = GUI()
EDIT:A. Rodas's code works.It seems that multithreading causes the problem.Deep reason remain unknown.
There's a good chance the problem is related to using threads -- calling Tkinter functions from anywhere other than the main thread can cause problems.
Is there a reason you're using a thread rather than takingbadvantage of the built-in infinite loop (the event loop)? I would advise making use of
after
to check the keyboard every second or so.I think multithreading isn't the best approach for your situation and
after
may be enough. Instead of a busy waiting loop, you can calltk.after
with a lower timeout. Then you just need to move the logic ofwatch_clipboard
to your class, so you don't have to worry about the communication between the threads.@laike9m
The error with your code is that os.pipe is used.
Os.read() is a blocking function that will receive os.read() blocking once
clipboard_confirm
is run. Causes the UI to get stuck.This bug has nothing to do with
after
and multithreading.