метод setMouseCallback не работает с tkinter?

#python #opencv #tkinter

#python #opencv #tkinter

Вопрос:

Я работаю над приложением слайд-шоу. В основном это показывает все изображения в определенном каталоге каждые 5 секунд, и если вы нажмете, изображение изменится. Он работал так хорошо, пока я не смешал его с tkinter . Похоже, мой setMouseCallback метод больше не работает… Что-нибудь помогает?

 import os
import cv2
import random
import tkinter as tk



root = tk.Tk()

mouseClickChecker=1

def func():
    
    def clickevent(event,x,y,flags,param):
        if event == cv2.EVENT_LBUTTONDOWN:
            global mouseClickChecker
            mouseClickChecker=2
    
    path = "./"

    file_list = os.listdir(path)

    file_list_jpg = [file for file in file_list if file.endswith('.jpg')]
    file_list_JPG = [file for file in file_list if file.endswith('.JPG')]
    file_list_jpeg = [file for file in file_list if file.endswith('.jpeg')]
    file_list_PNG= [file for file in file_list if file.endswith('.PNG')]
    file_list_png=[file for file in file_list if file.endswith('.png')]

    list_in_list = [file_list_jpg, file_list_PNG, file_list_JPG, file_list_jpeg,file_list_png]
    final_list = sum(list_in_list,[])

    logoPlayChecker=1

    while(True):

        random.shuffle(final_list)

        final_list[0]='logo.jpg'

        real_final_list=[]
    
        for v in final_list:
            if v not in real_final_list:
                real_final_list.append(v)
            
        print(real_final_list)
    
        for i in real_final_list:
            mouseClickChecker=1
            img = cv2.imread(i)
            
            winname = "slidshow"
            
            cv2.namedWindow(winname, cv2.WND_PROP_FULLSCREEN) ##WINDOW_NORMAL
            cv2.setWindowProperty(winname, cv2.WND_PROP_FULLSCREEN,cv2.WINDOW_FULLSCREEN)
            cv2.imshow(winname, img)

            if logoPlayChecker == 1:
                cv2.waitKey(3500)
                logoPlayChecker=2
            else:
                cv2.waitKey(100)

                for i in range(50):
                    
                    cv2.setMouseCallback(winname, clickevent)

                    if mouseClickChecker==2:
                        print(mouseClickChecker)
                        break
                    else:
                        mouseClickChecker=1
                        print(mouseClickChecker)
                        cv2.waitKey(100)

        logoPlayChecker=1


label = tk.Label(root, text='push button')

label.pack()

button = tk.Button(root, text = 'push!', command = func)

button.pack()

root.mainloop()
  

Ответ №1:

У Tkinter есть собственный метод захвата нажатий кнопок, и он, вероятно, блокирует обратный вызов cv2.

Вы можете зарегистрировать обратный вызов для нажатия кнопки в tkinter с помощью

 root.bind("<Button-1>", nameOfCallbackFunction)
  

Стоит отметить, что tkinter не работает с бесконечными циклами while, как вы определили внутри func

Чтобы решить эту проблему, я бы предложил переместить код из цикла в новую функцию, которая вызывается при нажатии.

Вы также должны удалить / заменить любые waitKey вызовы. Это заблокирует tkinter и не позволит ему реагировать на нажатия кнопок.