使用tkinter监视剪贴板,我的代码有什么问题? [英] Using tkinter to watch for clipboard,what's wrong with my code?

查看:171
本文介绍了使用tkinter监视剪贴板,我的代码有什么问题?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有关代码的一些描述:


  1. 这是我程序的一部分,我只将相关行放在这里

  2. 我希望这些代码能做的是监视剪贴板。如果我将 http:xxx 复制到剪贴板,则会显示一个弹出窗口。剪贴板的内容没有变化,窗口不会再次显示

  3. 运行时,它可以正常弹出窗口一次,但是当我再次运行时,它不会再次显示将另一个以'http:'
  4. 开头的字符串复制到剪贴板中。
  5. 我在之后尝试了一些不同的间隔值方法,结果相同。

代码:

 从tkinter导入* 
导入os
导入tkinter.messagebox作为消息框
导入线程
导入re

def watch_clipboard( tk,pipeout):
content =''
last_content =''
而True:
try:
content = tk.clipboard_get()
除了TclError:
传递
结果= re.match('http:',content)
如果内容!= last_content:
如果结果:
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('监视剪贴板')
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剪贴板_confirm(self,pipein):
message = os.read(pipein,16)
如果message == b'show':
self.tk.clipboard_clear()
messagebox.askokcancel('','add this in?',默认='ok')
self .tk.after(5000,如果__name__ =='__main__':#b $ b gui = GUI()


pre>

编辑:A。 Rodas的代码有效。似乎多线程导致了问题。深层原因仍然未知。

解决方案

我认为多线程并不是最好的方法并根据之后的情况进行处理。您可以在较短的超时时间内调用 tk.after 来代替繁忙的等待循环。然后,您只需要将 watch_clipboard 的逻辑移到您的类中,因此您不必担心线程之间的通信。

 类GUI:
def __init __(self):
self.tk = Tk()
self.tk.resizable( 0,0)
self.tk.title('监视剪贴板')
self.last_content =''
self.tk.after(100,self.watch_clipboard)
self .tk.mainloop()
def watch_clipboard(self):
try:
content = self.tk.clipboard_get()
if content!= self.last_content and content.startswith ('http:'):
self.last_content =内容
self.tk.clipboard_clear()
messagebox.askokcancel('','添加此内容?',默认='确定' )
,但TclError:
传递
self.tk.after(100,self.watch_clipboard)


Some description about the code:

  1. This is part of my program and I only put the related lines here
  2. 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
  3. 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:'
  4. 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.

解决方案

I think multithreading isn't the best approach for your situation and after may be enough. Instead of a busy waiting loop, you can call tk.after with a lower timeout. Then you just need to move the logic of watch_clipboard to your class, so you don't have to worry about the communication between the threads.

class GUI:
    def __init__(self):
        self.tk = Tk()
        self.tk.resizable(0, 0)
        self.tk.title('watch clipboard')
        self.last_content = ''
        self.tk.after(100, self.watch_clipboard)
        self.tk.mainloop()
    def watch_clipboard(self):
        try:
            content = self.tk.clipboard_get()
            if content != self.last_content and content.startswith('http:'):
                self.last_content = content
                self.tk.clipboard_clear()
                messagebox.askokcancel('', 'add this in?', default='ok')
        except TclError:
            pass
        self.tk.after(100, self.watch_clipboard)

这篇关于使用tkinter监视剪贴板,我的代码有什么问题?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆