如何在一个窗口中打开多个Tkinter窗口

时间:2014-05-10 19:51:21

标签: python tkinter

我有两个或更多python Tkinter文件。每个文件都打开一个窗口,如何在一个主窗口中运行所有Tkinter窗口功能。

例如:我有两个文件,一个是usbcam.py,它将打开USB摄像头并进行视频流动,另一个是ipcam.py,它打开IP摄像头并提供实时流媒体。这两个文件分别打开两个windows如何在一个窗口中使其工作

usbcam.py

import cv2
import PIL.Image
import PIL.ImageTk
import Tkinter as tk


def update_image(image_label, cv_capture):
    cv_image = cv_capture.read()[1]
    cv_image = cv2.cvtColor(cv_image, cv2.COLOR_BGR2RGB)
    pil_image = PIL.Image.fromarray(cv_image)
    pil_image.save('image3.jpg')
    tk_image = PIL.ImageTk.PhotoImage(image=pil_image)
    image_label.configure(image=tk_image)
    image_label._image_cache = tk_image  # avoid garbage collection
    root.update()


def update_all(root, image_label, cv_capture):
    if root.quit_flag:
        root.destroy()  # this avoids the update event being in limbo
    else:
        update_image(image_label, cv_capture)
        root.after(10, func=lambda: update_all(root, image_label, cv_capture))


if __name__ == '__main__':
    cv_capture = cv2.VideoCapture()
    cv_capture.open(0)  # have to use whatever your camera id actually is
    root = tk.Tk()
    setattr(root, 'quit_flag', False)
    def set_quit_flag():
        root.quit_flag = True
    root.protocol('WM_DELETE_WINDOW', set_quit_flag)  # avoid errors on exit
    image_label = tk.Label(master=root)  # the video will go here
    image_label.pack()
    root.after(0, func=lambda: update_all(root, image_label, cv_capture))
    root.mainloop()

ipcam.py

import cv2
import numpy as np
import PIL.Image
import PIL.ImageTk
import Tkinter as tk
import urllib

stream = urllib.urlopen("http://192.168.2.195:80/capture/scapture").read()
bytes_ = ''


def update_image(image_label):
    global bytes_
    bytes_ += stream.read(1024)
    a = bytes_.find('\xff\xd8')
    b = bytes_.find('\xff\xd9')
    if (a != -1) and (b != -1):
        jpg = bytes_[a:b+2]
        bytes_ = bytes_[b+2:]
        cv_image = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8),
                                cv2.CV_LOAD_IMAGE_COLOR)
        cv_image = cv2.cvtColor(cv_image, cv2.COLOR_BGR2RGB)
        pil_image = PIL.Image.fromarray(cv_image)
        tk_image = PIL.ImageTk.PhotoImage(image=pil_image)
        image_label.configure(image=tk_image)
        image_label._image_cache = tk_image  # avoid garbage collection
        root.update()


def update_all(root, image_label):

    if root.quit_flag:
        print "coming if"
        root.destroy()  # this avoids the update event being in limbo
    else:
        print "coming else"
        update_image(image_label)
        root.after(1, func=lambda: update_all(root, image_label))
def timer(interval = 100):
    root.after(0, func=lambda: update_all(root, image_label))
  #.................................................................................................
    root.after(interval, timer)

if __name__ == '__main__':
    root = tk.Tk()
    setattr(root, 'quit_flag', False)
    def set_quit_flag():
        root.quit_flag = True
    root.protocol('WM_DELETE_WINDOW', set_quit_flag)
    image_label = tk.Label(master=root)  # label for the video frame
    image_label.pack()
    root.after(2, func=lambda: update_all(root, image_label))
    # timer()
    root.mainloop()

2 个答案:

答案 0 :(得分:1)

您需要指定一个脚本作为主脚本,在那个脚本中您可以import另一个脚本。以下是使用Frame小部件的简单子类执行此操作的示例:

主要脚本(tkA.py):

from Tkinter import *
from tkB import Right # bring in the class Right from secondary script


class Left(Frame):
    '''just a frame widget with a white background'''
    def __init__(self, parent):
        Frame.__init__(self, parent, width=200, height=200)
        self.config(bg='white')

if __name__ == "__main__":
    # if this script is run, make an instance of the left frame from here
    # and right right frame from tkB
    root = Tk()
    Left(root).pack(side=LEFT) # instance of Left from this script
    Right(root).pack(side=RIGHT) # instance of Right from secondary script
    root.mainloop()

辅助脚本(tkB.py):

from Tkinter import *


class Right(Frame):
    '''just a frame widget with a black background'''
    def __init__(self, parent):
        Frame.__init__(self, parent, width=200, height=200)
        self.config(bg='black')

if __name__ == "__main__":
    # if this script is run, just do this:
    root = Tk()
    Right(root).pack()
    root.mainloop()

希望有所帮助。

答案 1 :(得分:0)

首先,您需要将其包含在顶部。所以在ipcam.py的顶部写下'import usbcam' (没有引用)。