Changeset - 2b850618ba88
[Not reviewed]
default
1 7 0
Laman - 6 years ago 2018-12-13 18:02:07

refactoring and debugging GUI
8 files changed with 48 insertions and 39 deletions:
0 comments (0 inline, 0 general)
src/core.py
Show inline comments
 
@@ -49,7 +49,7 @@ class Core:
 
	def putFrame(self,frame):
 
		self._frame=PIL.Image.fromarray(frame)
 
		k=self._cache.put(self._frame)
 
		self._guiMessages.send("setFrame", (self._frame, gui.RECORDING, k))
 
		self._guiMessages.send("setFrame", (self._frame, gui.REAL, k))
 
		self.analyze()
 

	
 
	def sendParams(self):
src/gui/__init__.py
Show inline comments
 
@@ -21,14 +21,15 @@ class GUI:
 
		self.root.option_add('*tearOff',False) # for menu
 

	
 
		self.detector=ImageAnalyzer()
 
		self._frame=None
 
		self._frameKey=0
 

	
 
		self._ownMessages=None
 
		self._coreMessages=None
 

	
 
		self._state=GUI.SETUP
 
		self._state=GUI.RECORDING
 

	
 
		self.mainWindow = MainWindow(self, master=self.root)
 
		self.mainWindow = MainWindow(self)
 
		self.settings=None
 
		self.root.columnconfigure(0,weight=1)
 
		self.root.rowconfigure(0,weight=1)
 
@@ -39,7 +40,7 @@ class GUI:
 
		self.root.bind("<F12>",lambda e: Settings(self))
 
		self.mainWindow.bind("<Destroy>",lambda e: self._shutDown())
 

	
 
		self.setUp()
 
		self.setRecording()
 

	
 
	def __call__(self,ownMessages,coreMessages):
 
		self._ownMessages=ownMessages
 
@@ -57,6 +58,7 @@ class GUI:
 
		self.mainWindow.setUp()
 
		self.root.bind("<Left>",lambda e: self.sendMsg("prevFrame"))
 
		self.root.bind("<Right>",lambda e: self.sendMsg("nextFrame"))
 
		self._state=GUI.SETUP
 

	
 
	def setRecording(self):
 
		self.mainWindow.setRecording()
 
@@ -65,11 +67,16 @@ class GUI:
 
		if self.settings:
 
			self.settings.destroy()
 
			self.settings=None
 
		self.sendParams()
 
		if self._coreMessages: self.sendParams()
 
		self._state=GUI.RECORDING
 

	
 
	def sendParams(self):
 
		self.sendMsg("setParams",(self.detector.params.copy(),))
 

	
 
	def preview(self):
 
		if self.detector.analyze(self._frame):
 
			self.mainWindow.boardView.redrawState(self.detector.board)
 

	
 
	def _shutDown(self):
 
		log.info("GUI proc exiting.")
 
		self._ownMessages.send("!kill",("gui",))
 
@@ -89,11 +96,15 @@ class GUI:
 
		if self._state!=type and self.mainWindow.imgView.isSet():
 
			log.info("ignored setFrame event, wrong type")
 
			return
 
		self._frame=frame
 
		self._frameKey=key
 
		self.mainWindow.setFrame(frame)
 
		self.root.event_generate("<<redrawImgView>>")
 

	
 
	def _stateHandler(self,gameState,moves):
 
		if self._state==GUI.SETUP:
 
			log.info("ignored incoming gameState")
 
			return
 
		labels={(row,col):(i+1) for (i,(c,row,col)) in enumerate(moves)}
 
		self.mainWindow.boardView.redrawState(gameState,labels)
 

	
src/gui/imgview.py
Show inline comments
 
@@ -13,10 +13,10 @@ log=logging.getLogger(__name__)
 

	
 

	
 
class ImgView(ResizableCanvas):
 
	def __init__(self,master=None,parent=None):
 
	def __init__(self,gui,master=None):
 
		super().__init__(master)
 

	
 
		self._parent=parent
 
		self._gui=gui
 
		self._corners=Corners()
 
		self._boardGrid=None
 

	
 
@@ -31,7 +31,9 @@ class ImgView(ResizableCanvas):
 
		self.delete("all")
 

	
 
		if self._img:
 
			img=self._img.resize((int(self._width),int(self._height)))
 
			w,h=self._img.size
 
			ratio=min(self._width/w, self._height/h)
 
			img=self._img.resize((int(w*ratio),int(h*ratio)))
 
			self._tkImg=ImageTk.PhotoImage(img) # just to save the image from garbage collector
 
			self.create_image(self._width//2, self._height//2, anchor="center", image=self._tkImg)
 

	
 
@@ -66,7 +68,8 @@ class ImgView(ResizableCanvas):
 
			log.debug(self._corners.corners)
 
			self._boardGrid=Grid(self._corners.corners)
 
			corners=[self._transformPoint(c) for c in self._corners.corners]
 
			self._parent.detector.setCorners(corners)
 
			self._gui.detector.setCorners(corners)
 
			self._gui.preview()
 

	
 
		self.redraw()
 

	
 
@@ -96,9 +99,10 @@ class ImgView(ResizableCanvas):
 
		w=int(self._width)
 
		h=int(self._height)
 
		wo,ho=self._img.size # o for original
 
		log.debug("image: %sx%s, view: %sx%s",wo,ho,w,h)
 
		widthRatio=wo/w
 
		heightRatio=ho/h
 
		self._imgSizeCoef=max(widthRatio,heightRatio)
 
		imgSizeCoef=max(widthRatio,heightRatio)
 
		# shift compensates possible horizontal or vertical empty margins from unmatching aspect ratios
 
		self._imgShift=EPoint(wo-w*self._imgSizeCoef,ho-h*self._imgSizeCoef)/2
 
		return EPoint(self.canvasx(point.x),self.canvasy(point.y)) * self._imgSizeCoef + self._imgShift
 
		imgShift=EPoint(wo-w*imgSizeCoef,ho-h*imgSizeCoef)/2
 
		return EPoint(self.canvasx(point.x),self.canvasy(point.y)) * imgSizeCoef + imgShift
src/gui/mainwindow.py
Show inline comments
 
import tkinter as tk
 
from tkinter import N,S,E,W
 

	
 
from .util import MsgMixin
 
from .menu import MainMenu
 
from .boardview import BoardView
 
from .imgview import ImgView
 
from .statusbar import StatusBar
 

	
 

	
 
class MainWindow(tk.Frame,MsgMixin):
 
	def __init__(self,parent,master=None):
 
class MainWindow(tk.Frame):
 
	def __init__(self,parent):
 
		self.parent=parent
 

	
 
		tk.Frame.__init__(self, master)
 
		tk.Frame.__init__(self, parent.root)
 
		self.grid(column=0,row=0,sticky=(N,S,E,W))
 
		self._createWidgets()
 

	
 
@@ -22,11 +21,11 @@ class MainWindow(tk.Frame,MsgMixin):
 
	def _createWidgets(self):
 
		# menu
 
		self.parent.root.option_add('*tearOff',False)
 
		self._menu=MainMenu(self.parent,self.parent.root)
 
		self._menu=MainMenu(self.parent)
 

	
 
		# a captured frame with overlay graphics
 
		self._imgWrapper=tk.Frame(self,width=480,height=360)
 
		self.imgView=ImgView(self._imgWrapper,self)
 
		self.imgView=ImgView(self.parent,self._imgWrapper)
 

	
 
		self._imgWrapper.grid(column=0,row=0,sticky=(N,S,E,W))
 

	
src/gui/menu.py
Show inline comments
 
import tkinter as tk
 

	
 
from .util import MsgMixin
 
from .settings import Settings
 

	
 

	
 
class MainMenu(MsgMixin):
 
	def __init__(self,parent,root):
 
		self.root=root
 
		self.parent=parent
 
class MainMenu:
 
	def __init__(self,gui):
 
		self.gui=gui
 
		self.root=gui.root
 
		self._createWidgets()
 

	
 
	def _createWidgets(self):
 
@@ -18,7 +17,7 @@ class MainMenu(MsgMixin):
 
		bar.add_cascade(menu=file, label='File')
 
		bar.add_cascade(menu=help_, label='Help')
 

	
 
		file.add_command(label="Settings",command=lambda: Settings(self.parent))
 
		file.add_command(label="Settings",command=lambda: Settings(self.gui))
 

	
 
		help_.add_command(label="About")
 

	
src/gui/settings.py
Show inline comments
 
import tkinter as tk
 
from tkinter import N,S,E,W,LEFT
 

	
 
from .util import MsgMixin
 

	
 

	
 
class Settings(tk.Toplevel,MsgMixin):
 
	def __init__(self,parent):
 
		self.parent=parent
 
class Settings(tk.Toplevel):
 
	def __init__(self,gui):
 
		self._gui=gui
 

	
 
		tk.Toplevel.__init__(self, parent.root)
 
		tk.Toplevel.__init__(self, gui.root)
 

	
 
		self.title("Settings | OneEye")
 

	
 
@@ -17,9 +15,9 @@ class Settings(tk.Toplevel,MsgMixin):
 
		self.content.grid(column=0,row=0,sticky=(N,S,E,W))
 
		self.content.columnconfigure(0,weight=1)
 
		self._create()
 
		self.parent.settings=self
 
		self.parent.root.event_generate("<<setUp>>")
 
		self.parent.sendMsg("fetchParams")
 
		self._gui.settings=self
 
		self._gui.root.event_generate("<<setUp>>")
 
		self._gui.sendMsg("fetchParams")
 

	
 
	def _create(self):
 
		self.scaleTresB=tk.Scale(self.content, orient=tk.HORIZONTAL, length=200, from_=0.0, to=100.0, command=self.refreshTresholds)
 
@@ -40,14 +38,15 @@ class Settings(tk.Toplevel,MsgMixin):
 
		self.cancelButton.pack(side=LEFT)
 

	
 
	def refreshTresholds(self,_):
 
		params=self.parent.detector.params
 
		params=self._gui.detector.params
 
		params.tresB=self.scaleTresB.get()
 
		params.tresW=self.scaleTresW.get()
 
		self._gui.preview()
 

	
 
	def setParams(self,params):
 
		self.scaleTresB.set(params.tresB)
 
		self.scaleTresW.set(params.tresW)
 

	
 
	def sendParams(self):
 
		self.parent.sendParams()
 
		self._gui.sendParams()
 
		self.destroy()
src/gui/util.py
Show inline comments
 
deleted file
src/util.py
Show inline comments
 
@@ -31,7 +31,7 @@ class MsgQueue:
 
			msg=self._queue.get()
 
			if self._queue.empty():
 
				self._event.clear()
 
			log.info(msg if msg[0]!="putFrame" else "('putFrame', ..., {})")
 
			log.info("%s <- %s", self.name, msg if msg[0]!="putFrame" else "('putFrame', ..., {})")
 
			if msg[0]=="!kill": break
 
			self._handleEvent(msg)
 
		log.info("%s MsgQueue exiting.",self.name)
0 comments (0 inline, 0 general)