我正在尝试将相机输入 GTK 窗口, 我想保持按钮按下事件和动作通知事件事件正常工作。
我找到了如何通过刷新 Gtk.image 中的图像来获取视频, 在 GLib.idle_add 中,尝试使用 thread.Threading,尝试使用 GLib.timeout_add, 但循环仍然阻塞事件。 我还尝试在虚拟环境中使用 OpenCV-headless...
我读了它:https://pygobject.readthedocs.io/en/latest/guide/threading.html
我什么没听懂?有办法解决这个问题吗?
这是我的(简化的)代码:
import cv2
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import GLib, Gtk, GdkPixbuf
#import threading
vdo_url="http://my_cam/vdo.mjpg" # simplified, without security
class Cam_GTK(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Cam GTK")
self.capture = cv2.VideoCapture(vdo_url)
self.video = Gtk.Image.new()
self.video.connect("button-press-event", self.on_video_clicked )
self.video.connect("motion-notify-event", self.on_video_hover )
# Also tried with event=Gtk.EventBox.new(), event.add(self.video), then "connect"...
page_box = Gtk.Box( orientation=Gtk.Orientation.VERTICAL, spacing=1 )
page_box.pack_start( self.video, True, True, 0 )
self.add(page_box)
GLib.idle_add(self.show_frame)
#GLib.timeout_add(100, self.show_frame)
#tried to Thread(target=self.show_frame) w/out loop
self.connect("destroy", Gtk.main_quit)
self.show_all()
def on_video_hover( self, event, result ):
print("video hover")
def on_video_clicked( self, event, button ):
print("video clicked")
def show_frame(self):
ret, frame = self.capture.read()
#tried with a while
if ret:
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
pb = GdkPixbuf.Pixbuf.new_from_data(frame.tobytes(),
GdkPixbuf.Colorspace.RGB,
False,
8,
frame.shape[1],
frame.shape[0],
frame.shape[2]*frame.shape[1])
self.video.set_from_pixbuf( pb.copy() )
return True #tried changed to False to stop loop
cam = Cam_GTK()
Gtk.main()
capture.read()
将阻塞,直到有新的帧可用。这将至少限制你的事件处理循环。
您需要生成一个线程,在循环中执行
capture.read()
操作,然后将新读取的帧发送到您的 GUI。