Question

I am having two or more python Tkinter files. Each file is opening one window, how can run all the Tkinter windows functionality in one main window.

Ex : I have two files one is usbcam.py which will open USB camera and give the video steaming and the other one is ipcam.py it opens the IP camera and give the live streaming.This two files are opening in two windows how can make this to work in one window

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()
Was it helpful?

Solution

You need to designate one script as the main script, and in that one you can import the other. Here's an example of doing this using a simple subclass of the Frame widget:

The primary script (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()

The secondary script (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()

Hope that helps.

OTHER TIPS

First, you need to include it in the top. So in the top of ipcam.py write 'import usbcam' (without quotations).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top