I have an arduino connected to a button. when the button is pressed, a serial output of 1 is sent via serial. i want the python tkinter stopwatch to start when the button is pressed. Currently i know 1 is being read by the python serial read. and prints out at python terminal. but i cant control the tkinter stopwatch. PS: i am fairly new to python. below is my current code.
from tkinter import *
import time
import serial
ser = serial.Serial(
port='COM4',\
baudrate=57600,\
parity=serial.PARITY_NONE,\
stopbits=serial.STOPBITS_ONE,\
bytesize=serial.EIGHTBITS,\
timeout=10)
print("connected to: " + ser.portstr)
class StopWatch(Frame):
""" Implements a stop watch frame widget. """
def __init__(self, parent=None, **kw):
Frame.__init__(self, parent, kw)
self._start = 0.0
self._elapsedtime = 0.0
self._running = 0
self.timestr = StringVar()
self.makeWidgets()
def makeWidgets(self):
""" Make the time label. """
l = Label(self, textvariable=self.timestr)
self._setTime(self._elapsedtime)
l.pack(fill=X, expand=NO, pady=2, padx=2)
def _update(self):
""" Update the label with elapsed time. """
self._elapsedtime = time.time() - self._start
self._setTime(self._elapsedtime)
self._timer = self.after(50, self._update)
def _setTime(self, elap):
""" Set the time string to Minutes:Seconds:Hundreths """
minutes = int(elap/60)
seconds = int(elap - minutes*60.0)
hseconds = int((elap - minutes*60.0 - seconds)*100)
self.timestr.set('%02d:%02d:%02d' % (minutes, seconds, hseconds))
def Start(self):
""" Start the stopwatch, ignore if running. """
if not self._running:
self._start = time.time() - self._elapsedtime
self._update()
self._running = 1
def Stop(self):
""" Stop the stopwatch, ignore if stopped. """
if self._running:
self.after_cancel(self._timer)
self._elapsedtime = time.time() - self._start
self._setTime(self._elapsedtime)
self._running = 0
def Reset(self):
""" Reset the stopwatch. """
self._start = time.time()
self._elapsedtime = 0.0
self._setTime(self._elapsedtime)
def main():
root = Tk()
sw = StopWatch(root)
sw.pack(side=TOP)
root.mainloop()
if __name__ == '__main__':
main()
root = Tk()
sw = StopWatch(root)
sw.pack(side=TOP)
count=1
while True:
for line in ser.read():
print(chr(line))
count = count+1
if chr(line) == '1':
sw.Start()
ser.close()
Edit: As per comment answer by i have got it working. below is the working code.
from tkinter import *
import time
import serial
class StopWatch(Frame):
""" Implements a stop watch frame widget. """
def __init__(self, parent=None, **kw):
Frame.__init__(self, parent, kw)
self._start = 0.0
self._elapsedtime = 0.0
self._running = 0
self.timestr = StringVar()
self.makeWidgets()
def makeWidgets(self):
""" Make the time label. """
l = Label(self, textvariable=self.timestr)
self._setTime(self._elapsedtime)
l.pack(fill=X, expand=NO, pady=2, padx=2)
def _update(self):
""" Update the label with elapsed time. """
self._elapsedtime = time.time() - self._start
self._setTime(self._elapsedtime)
self._timer = self.after(50, self._update)
def _setTime(self, elap):
""" Set the time string to Minutes:Seconds:Hundreths """
minutes = int(elap/60)
seconds = int(elap - minutes*60.0)
hseconds = int((elap - minutes*60.0 - seconds)*100)
self.timestr.set('%02d:%02d:%02d' % (minutes, seconds, hseconds))
def Start(self):
""" Start the stopwatch, ignore if running. """
if not self._running:
self._start = time.time() - self._elapsedtime
self._update()
self._running = 1
def Stop(self):
""" Stop the stopwatch, ignore if stopped. """
if self._running:
self.after_cancel(self._timer)
self._elapsedtime = time.time() - self._start
self._setTime(self._elapsedtime)
self._running = 0
def Reset(self):
""" Reset the stopwatch. """
self._start = time.time()
self._elapsedtime = 0.0
self._setTime(self._elapsedtime)
def Read():
ser = serial.Serial(
port='COM4',\
baudrate=57600,\
parity=serial.PARITY_NONE,\
stopbits=serial.STOPBITS_ONE,\
bytesize=serial.EIGHTBITS,\
timeout=10)
print("connected to: " + ser.portstr)
count=1
while True:
for line in ser.read():
print(chr(line))
count = count+1
return chr(line)
ser.close()
def main():
root = Tk()
sw = StopWatch(root)
sw.pack(side=TOP)
ser = Read()
if ser == '1':
sw.Start()
root.mainloop()
if __name__ == '__main__':
main()
You main() and if __name__ statements are a bit broken.
You code will not run as you think it will according to what I can see in your code.
You should only be creating one instance of Tk() and in your code it is written twice.
Note that any code you have written after root.mainloop() will not run until mainloop() has ended. At that point your program will be closed and a new instance will have been created due to the rest of your main() statement.
This is probably not your intention.
This:
def main():
root = Tk()
sw = StopWatch(root)
sw.pack(side=TOP)
root.mainloop()
if __name__ == '__main__':
main()
root = Tk()
sw = StopWatch(root)
sw.pack(side=TOP)
count=1
while True:
for line in ser.read():
print(chr(line))
count = count+1
if chr(line) == '1':
sw.Start()
ser.close()
Should probably look like this:
def main():
root = Tk()
sw = StopWatch(root)
sw.pack(side=TOP)
count=1
while True:
for line in ser.read():
print(chr(line))
count = count+1
if chr(line) == '1':
sw.Start()
ser.close()
root.mainloop()
if __name__ == '__main__':
main()
This is not an attempt to answer your overall problem as I have not looked at all of your code in detail yet but it would have been hard to place in a comment so I wrote it here.
UPDATE:
I am not able to test your code on anything serial related however I did modify your for loop to test the functionality of your code. With that said I believe you want to move the contents of ser = serial.Serial() into the main() function just before the while loop. Also maybe you should change the while loop statement just a bit. Currently the statement while True: will run forever.
Instead use something like this.
x = True
while x == True:
# do stuff
x = False
sw.Start()
In the end I think you code should look like this:
from tkinter import *
import time
import serial
class StopWatch(Frame):
""" Implements a stop watch frame widget. """
def __init__(self, parent=None, **kw):
Frame.__init__(self, parent, kw)
self._start = 0.0
self._elapsedtime = 0.0
self._running = 0
self.timestr = StringVar()
self.makeWidgets()
def makeWidgets(self):
""" Make the time label. """
l = Label(self, textvariable=self.timestr)
self._setTime(self._elapsedtime)
l.pack(fill=X, expand=NO, pady=2, padx=2)
def _update(self):
""" Update the label with elapsed time. """
self._elapsedtime = time.time() - self._start
self._setTime(self._elapsedtime)
self._timer = self.after(50, self._update)
def _setTime(self, elap):
""" Set the time string to Minutes:Seconds:Hundreths """
minutes = int(elap/60)
seconds = int(elap - minutes*60.0)
hseconds = int((elap - minutes*60.0 - seconds)*100)
self.timestr.set('%02d:%02d:%02d' % (minutes, seconds, hseconds))
def Start(self):
""" Start the stopwatch, ignore if running. """
if not self._running:
self._start = time.time() - self._elapsedtime
self._update()
self._running = 1
def Stop(self):
""" Stop the stopwatch, ignore if stopped. """
if self._running:
self.after_cancel(self._timer)
self._elapsedtime = time.time() - self._start
self._setTime(self._elapsedtime)
self._running = 0
def Reset(self):
""" Reset the stopwatch. """
self._start = time.time()
self._elapsedtime = 0.0
self._setTime(self._elapsedtime)
def main():
root = Tk()
sw = StopWatch(root)
sw.pack(side=TOP)
ser = serial.Serial(
port='COM4',\
baudrate=57600,\
parity=serial.PARITY_NONE,\
stopbits=serial.STOPBITS_ONE,\
bytesize=serial.EIGHTBITS,\
timeout=10)
x = True
count=1
while x == True:
for line in ser.read():
print(chr(line))
count = count+1
if chr(line) == '1':
sw.Start()
root.mainloop()
if __name__ == '__main__':
main()
Related
I have been working on a music player app that uses VLC to play songs directly from the internet and has features like seeking and a progress bar. But as the normal tkinter progress bar looks kinda old so I used customtkinter.CTkSlider widget but using this causes buffering. The song plays smoothly on using Tk.Scale.
Here, is the code:
# import external libraries
import vlc
import tkinter as Tk
from tkinter import ttk
import pyautogui
import customtkinter
import pafy
# import standard libraries
import os
from threading import Thread, Event
import time
import platform
import requests
class ttkTimer(Thread):
"""a class serving same function as wxTimer... but there may be better ways to do this
"""
def __init__(self, callback, tick):
Thread.__init__(self)
self.callback = callback
self.stopFlag = Event()
self.tick = tick
self.iters = 0
def run(self):
while not self.stopFlag.wait(self.tick):
self.iters += 1
self.callback()
def stop(self):
self.stopFlag.set()
def get(self):
return self.iters
class Player(Tk.Frame):
"""The main window has to deal with events.
"""
def __init__(self, parent, title=None):
Tk.Frame.__init__(self, parent)
self.parent = parent
if title == None:
title = "tk_vlc"
self.parent.title(title)
# Menu Bar
# File Menu
menubar = Tk.Menu(self.parent)
self.parent.config(menu=menubar)
fileMenu = Tk.Menu(menubar)
fileMenu.add_command(label="Open", underline=0, command=self.OnOpen)
fileMenu.add_command(label="Exit", underline=1, command=_quit)
menubar.add_cascade(label="File", menu=fileMenu)
# The second panel holds controls
self.player = None
self.videopanel = ttk.Frame(self.parent)
self.canvas = Tk.Canvas(self.videopanel).pack(fill=Tk.BOTH,expand=1)
self.videopanel.pack(fill=Tk.BOTH,expand=1)
ctrlpanel = ttk.Frame(self.parent)
pause = ttk.Button(ctrlpanel, text="Pause", command=self.OnPause)
play = ttk.Button(ctrlpanel, text="Play", command=self.OnPlay)
stop = ttk.Button(ctrlpanel, text="Stop", command=self.OnStop)
volume = ttk.Button(ctrlpanel, text="Volume", command=self.OnSetVolume)
pause.pack(side=Tk.LEFT)
play.pack(side=Tk.LEFT)
stop.pack(side=Tk.LEFT)
volume.pack(side=Tk.LEFT)
self.volume_var = Tk.IntVar()
self.volslider = Tk.Scale(ctrlpanel, variable=self.volume_var, command=self.volume_sel,
from_=0, to=100, orient=Tk.HORIZONTAL, length=100)
self.volslider.pack(side=Tk.LEFT)
ctrlpanel.pack(side=Tk.BOTTOM)
ctrlpanel2 = ttk.Frame(self.parent)
self.scale_var = Tk.DoubleVar()
self.timeslider_last_val = ""
self.timeslider = customtkinter.CTkSlider(ctrlpanel2, variable=self.scale_var, command=self.scale_sel,
from_=0, to=1000, orient=Tk.HORIZONTAL) # This causes buffer
self.timeslider.pack(side=Tk.BOTTOM, fill=Tk.X,expand=1)
self.timeslider_last_update = time.time()
ctrlpanel2.pack(side=Tk.BOTTOM,fill=Tk.X)
# VLC player controls
self.Instance = vlc.Instance()
self.player = self.Instance.media_player_new()
self.timer = ttkTimer(self.OnTimer, 1.0)
self.timer.start()
self.parent.update()
#self.player.set_hwnd(self.GetHandle()) # for windows, OnOpen does does this
def Extract(self,topic):
"""Will play video on following topic, takes about 10 to 15 seconds to load"""
url = 'https://www.youtube.com/results?q=' + topic
count = 0
cont = ''
try:
cont = requests.get(url)
except:
print('Error','Cannot Connect.. Internet not connected or invalid URL or id.')
cont = ''
data = cont.content
data = str(data)
lst = data.split('"')
for i in lst:
count+=1
if i == 'WEB_PAGE_TYPE_WATCH':
break
if lst[count-5] == "/results":
print("Error","No video found.")
return "https://www.youtube.com"+lst[count-5]
def OnExit(self, evt):
"""Closes the window.
"""
self.Close()
def OnOpen(self):
"""Pop up a new dialow window to choose a file, then play the selected file.
"""
# if a file is already running, then stop it.
self.OnStop()
fullname = pafy.new(self.Extract(pyautogui.password(mask="", title="Enter Song Name:", text="Enter Song Name:"))).getbest().url
self.Media = self.Instance.media_new(fullname)
self.player.set_media(self.Media)
# set the window id where to render VLC's video output
if platform.system() == 'Windows':
self.player.set_hwnd(self.GetHandle())
else:
self.player.set_xwindow(self.GetHandle()) # this line messes up windows
# FIXME: this should be made cross-platform
self.OnPlay()
# set the volume slider to the current volume
#self.volslider.SetValue(self.player.audio_get_volume() / 2)
self.volslider.set(self.player.audio_get_volume())
def OnPlay(self):
"""Toggle the status to Play/Pause.
If no file is loaded, open the dialog window.
"""
# check if there is a file to play, otherwise open a
# Tk.FileDialog to select a file
if not self.player.get_media():
self.OnOpen()
else:
# Try to launch the media, if this fails display an error message
if self.player.play() == -1:
self.errorDialog("Unable to play.")
def GetHandle(self):
return self.videopanel.winfo_id()
#def OnPause(self, evt):
def OnPause(self):
"""Pause the player.
"""
self.player.pause()
def OnStop(self):
"""Stop the player.
"""
self.player.stop()
# reset the time slider
self.timeslider.set(0)
def OnTimer(self):
"""Update the time slider according to the current movie time.
"""
if self.player == None:
return
# since the self.player.get_length can change while playing,
# re-set the timeslider to the correct range.
length = self.player.get_length()
dbl = length * 0.001
self.timeslider.config(to=dbl)
# update the time on the slider
tyme = self.player.get_time()
if tyme == -1:
tyme = 0
dbl = tyme * 0.001
self.timeslider_last_val = ("%.0f" % dbl) + ".0"
# don't want to programatically change slider while user is messing with it.
# wait 2 seconds after user lets go of slider
if time.time() > (self.timeslider_last_update + 2.0):
self.timeslider.set(dbl)
def scale_sel(self, evt):
if self.player == None:
return
nval = self.scale_var.get()
sval = str(nval)
if self.timeslider_last_val != sval:
self.timeslider_last_update = time.time()
mval = "%.0f" % (nval * 1000)
self.player.set_time(int(mval)) # expects milliseconds
def volume_sel(self, evt):
if self.player == None:
return
volume = self.volume_var.get()
if volume > 100:
volume = 100
if self.player.audio_set_volume(volume) == -1:
self.errorDialog("Failed to set volume")
def OnToggleVolume(self, evt):
"""Mute/Unmute according to the audio button.
"""
is_mute = self.player.audio_get_mute()
self.player.audio_set_mute(not is_mute)
# update the volume slider;
# since vlc volume range is in [0, 200],
# and our volume slider has range [0, 100], just divide by 2.
self.volume_var.set(self.player.audio_get_volume())
def OnSetVolume(self):
"""Set the volume according to the volume sider.
"""
volume = self.volume_var.get()
# vlc.MediaPlayer.audio_set_volume returns 0 if success, -1 otherwise
if volume > 100:
volume = 100
if self.player.audio_set_volume(volume) == -1:
self.errorDialog("Failed to set volume")
def errorDialog(self, errormessage):
"""Display a simple error dialog.
"""
Tk.tkMessageBox.showerror(self, 'Error', errormessage)
def Tk_get_root():
if not hasattr(Tk_get_root, "root"): #(1)
Tk_get_root.root= Tk.Tk() #initialization call is inside the function
return Tk_get_root.root
def _quit():
print("_quit: bye")
root = Tk_get_root()
root.quit() # stops mainloop
root.destroy() # this is necessary on Windows to prevent
# Fatal Python Error: PyEval_RestoreThread: NULL tstate
os._exit(1)
if __name__ == "__main__":
# Create a Tk.App(), which handles the windowing system event loop
root = Tk_get_root()
root.protocol("WM_DELETE_WINDOW", _quit)
player = Player(root, title="tkinter vlc")
# show the player window centred and run the application
root.mainloop()
Kindly help
Regards.
I have created a touch screen buttons consist of "start" "Request material" "Receive material" "Lap" "Emergency" "Finish"
Now i am trying to store integers as numbers of finished products (1,2,3,etc) and lap times when an operator presses the lap button (similar to stopwatch). Basically, there are only two columns. The result shows in the terminal after i ran the program and there was no error, but it didn't show in the mysql database and i am using phpmyadmin. Here is my code can be seen below:
from Tkinter import *
from pymodbus.client.sync import ModbusTcpClient as ModbusClient
import time
import datetime
import RPi.GPIO as GPIO
import MySQLdb
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(0)
#-------------------------------------------------------GPIO
GPIO.setup(21, GPIO.OUT)#red led
GPIO.setup(20, GPIO.OUT)#yellow led
GPIO.setup(16, GPIO.OUT)#green led
GPIO.output(21, GPIO.HIGH)
GPIO.output(20, GPIO.HIGH)
GPIO.output(16, GPIO.HIGH)
#-------------------------------------------------------GPIO
class Screen(Frame):
def __init__(self, master):
Frame.__init__(self, master)
#-------------------------------------------------------Main
self.lbttn_clicks = 0
self.start_button()
self.material_button()
self.receive_button()
self.emergency_button()
self.lap_button()
self.finish_button()
self.minutes = 0
self.seconds = 0
#-------------------------------------------------------Modbus Var
self.LedRed_State = False
self.LedYellow_State = False
self.LedGreen_State = False
self.db = MySQLdb.connect("localhost","root","raspberry","DB_ASSY")
self.sql = "INSERT INTO Table_Assembly (Finished Product, Lap Time) VALUES (%s, %s)"
self.c= self.db.cursor()
self.client = ModbusClient('192.168.4.166')
self.client.connect()
print "ModbusClient connected..."
#-------------------------------------------------------Modbus Var
self.time_start = time.time()
self.pack(fill=BOTH, expand=1)
#-------------------------------------------------------Main
#-------------------------------------------------------Stopwatch
self._start = 0.0
self._elapsedtime = 0.0
self._running = 0
self.timestr = StringVar()
# self.makeWidgets()
#-------------------------------------------------------Stopwatch
#--------------------------------------------------------------------Main funcs
def start_button(self):
self.gbttn = Button(self)
self.gbttn['text'] = "Start"
self.gbttn['command'] = lambda: [ f() for f in [self.Start,
self.LedGreen, self.LedYellowOff, self.LedRedOff]]
self.gbttn.place(x = 100, y = 0)
def material_button(self):
self.ybttn = Button(self)
self.ybttn['text'] = "Request Material"
self.ybttn['command'] = self.LedYellow
self.ybttn.place(x=100, y=50)
def receive_button(self):
self.rbttn = Button(self)
self.rbttn ['text'] = "Receive Material"
self.rbttn ['command'] = self.LedYellowOff
self.rbttn.place(x=100, y=100)
def emergency_button(self):
self.ebttn = Button(self)
self.ebttn['text'] = "Emergency"
self.ebttn['command'] = lambda: [f() for f in [self.LedRed, self.LedYellowOff, self.LedGreenOff]]
self.ebttn.place(x=100,y=150)
def lap_button(self):
self.lbttn = Button(self)
self.lbttn['text'] = "Lap"
self.lbttn['command'] = lambda: [ f() for f in [self.lap_count, self.Start, self.insert_to_db]]
self.lbttn.place(x=100,y=200)
def finish_button(self):
self.fbttn = Button(self)
self.fbttn['text'] = "Finish"
self.fbttn['command'] = lambda: [f() for f in [self.Finish, self.Stop, self.Reset]]
self.fbttn.place(x=100, y=250)
def lap_count(self):
self.lbttn_clicks += 1
print str(self.lbttn_clicks)
# def stop_watch(self):
# print self.seconds
# time.sleep(1)
# self.seconds = int(time.time() - self.time_start)
#--------------------------------------------------------------------------------------Main funcs
#--------------------------------------------------------------------------------------Modbus funcs
#--------------------------------------------------------------------------------------Modbus funcs
#--------------------------------------------------------------------------------------Stopwatch funcs
# def makeWidgets(self):
# """ Print the time. """
# l = Label(self, textvariable=self.timestr)
# self._setTime(self._elapsedtime)
# l.pack(fill=X, expand=NO, pady=2, padx=2)
def _print(self):
print self._elapsedtime
def _update(self):
""" Update the label with elapsed time. """
self._elapsedtime = time.time() - self._start
self._setTime(self._elapsedtime)
self._timer = self.after(50, self._update)
def _setTime(self, elap):
""" Set the time string to Minutes:Seconds:Hundreths """
minutes = int(elap / 60)
seconds = int(elap - minutes * 60.0)
hseconds = int((elap - minutes * 60.0 - seconds) * 100)
self.timestr.set('%02d:%02d:%02d' % (minutes, seconds, hseconds))
def Start(self):
""" Start the stopwatch, ignore if running. """
print self._elapsedtime
if not self._running:
self._start = time.time() - self._elapsedtime
self._update()
self._running = 1
def insert_to_db(self):
self.sql = "INSERT INTO Table_Assembly ('Finished_Product', 'Lap_Time') VALUES (%s, %s)"
try:
self.execute(sql,( str(self.lbttn_clicks), str(self._elapsedtime)))
self.db.commit()
except:
self.db.rollback()
def read_from_db(self):
try:
#c.execute("SELECT * FROM TTAB_CPU WHERE ID = (SELCET MAX(ID) FROM TAB_CPU)")
self.c.execute("SELECT * FROM Table_Assembly ORDER BY ID DESC LIMIT 1")
self.result = self.c.fetchall()
if result is not None:
print ('Finished_Product: ' , result[0][1], '| Lap_Time: ' , result[0][2])
except:
print ("read error")
def LedGreen(self):
self.rr = self.client.read_coils(0,6)
print "Start Button Pressed"
if self.LedGreen_State == False:
self.rr.bits[3] = True
self.rq = self.client.write_coil(3, True)
self.rq = self.client.write_coil(0, True)
GPIO.output(16, GPIO.LOW)
self.LedGreen_State = True
def LedGreenOff(self):
self.rr = self.client.read_coils(0,6)
print "Green light is off"
if self.LedGreen_State == True:
self.rr.bits[3] = False
self.rq = self.client.write_coil(3, False)
self.rq = self.client.write_coil(0, False)
GPIO.output(16, GPIO.HIGH)
self.LedGreen_State = False
def LedYellow(self):
self.rr = self.client.read_coils(0,6)
print "Request Material"
if self.LedYellow_State == False:
self.rr.bits[4] = True
self.rq = self.client.write_coil(4, True)
self.rq = self.client.write_coil(1, True)
GPIO.output(20, GPIO.LOW)
self.LedYellow_State = True
def LedYellowOff(self):
self.rr = self.client.read_coils(0,6)
print "Material replenished"
if self.LedYellow_State == True:
self.rr.bits[4] = False
self.rq = self.client.write_coil(4, False)
self.rq = self.client.write_coil(1, False)
GPIO.output(20, GPIO.HIGH)
self.LedYellow_State = False
def LedRed(self):
self.rr = self.client.read_coils(0,6)
print "Assembly process jammed"
if self.LedRed_State == False:
self.rr.bits[5] = True
self.rq = self.client.write_coil(5, True)
self.rq = self.client.write_coil(2, True)
GPIO.output(21, GPIO.LOW)
self.LedRed_State = True
def LedRedOff(self):
self.rr = self.client.read_coils(0,6)
print "Red light is off"
if self.LedRed_State == True:
self.rr.bits[5] = False
self.rq = self.client.write_coil(5, False)
self.rq = self.client.write_coil(2, False)
GPIO.output(21, GPIO.HIGH)
self.LedRed_State = False
def Finish(self):
self.rr = self.client.read_coils(0,6)
print "Assembly is finished"
if self.LedGreen_State == True:
self.rr.bits[3] = False
self.rq = self.client.write_coil(3, False)
self.rq = self.client.write_coil(0, False)
GPIO.output(16, GPIO.HIGH)
self.LedGreen_State = False
if self.LedYellow_State == True:
self.rr.bits[4] = False
self.rq = self.client.write_coil(4, False)
self.rq = self.client.write_coil(1, False)
GPIO.output(20, GPIO.HIGH)
self.LedYellow_State = False
if self.LedRed_State == True:
self.rr.bits[5] = False
self.rq = self.client.write_coil(5, False)
self.rq = self.client.write_coil(2, False)
GPIO.output(21, GPIO.HIGH)
self.LedRed_State = False
def Stop(self):
""" Stop the stopwatch, ignore if stopped. """
if self._running:
self.after_cancel(self._timer)
self._elapsedtime = time.time() - self._start
self._setTime(self._elapsedtime)
self._running = 0
GPIO.cleanup()
def Reset(self):
""" Reset the stopwatch. """
self._start = time.time()
self._elapsedtime = 0.0
self._setTime(self._elapsedtime)
def main():
while 1:
insert_to_db()
read_from_db()
if __name__ == '__main__':
try:
db = MySQLdb.connect("localhost","root","raspberry","DB_ASSY")
self.c= self.db.cursor()
except:
print ("No connection to server...")
win = Tk()
win.title("Screen")
win.geometry('800x400')
app = Screen(win)
win.mainloop()
Please share
Thank you
and by the way i am using raspberry pi with raspbian stretch
Every transnational(Insert, update and delete) query required to commit than after reflect db engine. So try with autocommit(True) or commit manual after query execution.
self.db = MySQLdb.connect("localhost","root","raspberry","DB_ASSY")
self.sql = "INSERT INTO Table_Assembly (Finished Product, Lap Time) VALUES (%s, %s)"
self.c= self.db.cursor()
self.db.commit()
I am trying to start a function with a new thread and everytime i start the function, the tkinter application opens up again. For me to see the function running i need to quit the new application that opened and then it starts. Is there something in my code that is calling the application again and not allowing my startReceive function to run instantly when i start the thread?
import tkinter as tk
from udpTransfer1 import UdpClass
from threading import Thread
from tkinter import messagebox
import multiprocessing, time, signal
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.alert = ''
self.pack()
self.alive = False
self.create_widgets()
self.c = UdpClass()
self.threadExists= False
self.st = None
def create_widgets(self):
# 1 button
self.hi_there = tk.Button(self)
self.hi_there["text"] = "Save UDP"
self.hi_there["command"] = self.run
self.hi_there.pack(side="top")
# 2 button
self.b2 = tk.Button(self)
self.b2["text"] = "Stop UDP"
self.b2["command"] = self.b2Action
self.b2.pack(side="top")
# 3 button
self.quit = tk.Button(self, text="QUIT", fg="red")
self.quit["command"] = self.kill
self.quit.pack(side="bottom")
def kill(self):
if self.threadExists == True:
# Alert Box
# self.alert = messagebox.showinfo("ALERT").capitalize()
self.alert = messagebox._show(None,'UDP has to be stopped first!')
else:
root.destroy()
def run(self):
# self.st = Thread(target=self.c.startReceive)
# self.st = multiprocessing.Process(target=self.c.startReceive)
self.st = multiprocessing.Process(target=startReceive)
self.st.start()
if (self.st.is_alive()):
print("Thread open")
self.threadExists = True
def b2Action(self):
if self.threadExists:
# self.c.terminate()
terminate()
self.st.terminate()
time.sleep(.1)
if not(self.st.is_alive()):
print("Thread Killed")
self.threadExists = False
else :
self.alert = messagebox._show(None, 'No Detection of UDP Running!')
def startReceive():
print('started')
try:
isRunning = True
# csvfile = open(self.filename, 'w')
# spamwriter = csv.writer(csvfile, delimiter=',', quotechar='|', quoting=csv.QUOTE_MINIMAL)
# start_time = time.time()
while isRunning:
print('done')
time.sleep(1)
except:
print('out')
def terminate():
# self.socket.close()
# isRunning = False
print('stopped')
root = tk.Tk()
app = Application(master=root)
app.master.title("UDP Saving")
app.master.geometry('200x200')
app.master.maxsize(200, 500)
app.mainloop()
Not 100% sure, but this might be the issue:
def run(self):
# self.st = Thread(target=self.c.startReceive)
# self.st = multiprocessing.Process(target=self.c.startReceive)
self.st = multiprocessing.Process(target=startReceive)
self.st.start()
if (self.st.is_alive()):
print("Thread open")
self.threadExists = True
I think You should put self.threadExists = True inside previous if.
def run(self):
# self.st = Thread(target=self.c.startReceive)
# self.st = multiprocessing.Process(target=self.c.startReceive)
self.st = multiprocessing.Process(target=startReceive)
self.st.start()
if (self.st.is_alive()):
print("Thread open")
self.threadExists = True
So I have this code in Python:
class Chronometre(Frame):
def __init__(self, parent=None, **kw):
Frame.__init__(self, parent, kw)
self._start = 0.0
self._elapsedtime = 0.0
self._running = 0
self.timestr = StringVar()
self.makeWidgets()
def _update(self):
self._elapsedtime = time.time() - self._start
self._setTime(self._elapsedtime)
self._timer = self.after(50, self._update)
def Start(self):
if not self._running:
self._start = time.time() - self._elapsedtime
self._update()
self._running = 1
def Stop(self):
if self._running:
self.after_cancel(self._timer)
self._elapsedtime = time.time() - self._start
self._setTime(self._elapsedtime)
self._running = 0
def Reset(self):
self._start = time.time()
self._elapsedtime = 0.0
self._setTime(self._elapsedtime)
def Clavier(event):
print(event.keysym)
if event.keysym == 'a' :
sw = Chronometre()
sw.Start()
sv = Chronometre()
sv.Start()
if event.keysym == 'z' :
sw = Chronometre()
sw.Stop()
if event.keysym == 'e' :
sv = Chronometre()
sv.Stop()
if event.keysym == 'r' :
sw = Chronometre()
sw.Reset()
sv = Chronometre()
sv.Reset()
def main():
root = Tk()
root.bind("<Key>",Clavier)
A friend of mine is trying to launch a function upon hitting a key, but it doesn't launch the function. Does anybody know why this would happen? I know the program goes into the if statement but it won't launch the function.
Could it be because of the fact that it is in a class?
You don't seem to be instantiating your classes, or calling their methods.
if event.keysym == 'a' :
sw = Chronometre()
sw.Start()
and so on.
First, you have to run the Tkinter mainloop for it to do anything, like catch keys
root.mainloop()
Second, the Start() function has variables that have not been declared, so you will get an error the first time through, i.e. self._running and self._elapsedtime. Also the function _setTime() has not been declared.
I'm trying to make a multithreaded program with Python, OpenCV, and Tkinter.
My program has some general point.
Load Video from file
Create 2 thread
1st thread to fetch frames from capture object and put it to python Queue
2nd thread to get the frames from Queue
At last, if possible, start and stop the capture object
However, my script seems to behave weirdly. Sometimes it can finish playing video until the end, but sometimes it also crash at some point of the video. Here is what I've got so far.
from Tkinter import Tk, Text
from Tkinter import PhotoImage
from ttk import Frame, Scrollbar, Button, Label
from PIL import Image, ImageTk
import cv
import time
import Queue
import threading
def writeToLog(log, msg):
numlines = log.index('end - 1 line').split('.')[0]
if log.index('end-1c')!='1.0': log.insert('end', '\n')
log.insert('end', msg)
log.see('end')
def GetIplImageMode(img):
orientation = 1 if img.origin == 0 else -1
mode_list = {(1, cv.IPL_DEPTH_8U) : ("L", "L", 1),\
(3, cv.IPL_DEPTH_8U) : ("BGR", "RGB", 3),\
(1, cv.IPL_DEPTH_32F) : ("F", "F", 4)}
key = (img.nChannels, img.depth)
modes = mode_list[key]
return [modes[0], modes[1], orientation]
def IplImage2PIL(img, mode):
return Image.fromstring(mode[1], (img.width, img.height),\
img.tostring(), "raw", mode[0],\
img.width * img.channels,\
mode[2])
def ResizePILImage(pil, width = 260, height = 180):
return pil.resize((width, height), Image.ANTIALIAS)
def PIL2TkImage(pil):
return ImageTk.PhotoImage(pil)
def setImageLabelFromIplImage(label, img_ipl):
mode = GetIplImageMode(img_ipl)
img_pil = IplImage2PIL(img_ipl, mode)
img_resized = ResizePILImage(img_pil)
img_tk = PIL2TkImage(img_resized)
label.configure(image = img_tk)
label.image = img_tk
def setImageLabelFromFile(label, szFileName):
img_ipl = cv.LoadImage(szFileName)
setImageLabelFromIplImage(label, img_ipl)
def mat_from_ipl(ipl):
return cv.GetMat(ipl)
def ipl_from_mat(mat):
ipl = cv.CreateImageHeader((mat.width, mat.height),\
cv.IPL_DEPTH_8U, mat.channels)
cv.SetData(ipl, mat.tostring())
return ipl
class asdf(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.pack(fill='both', expand=True)
self.parent = parent
self.variables()
self.ui()
def variables(self):
self.ctr = 0
self.fps = 0
self.video = None
self.image = None
self.putProc = None
self.getProc = None
self.isRunning = False
self.queue = Queue.Queue()
def ui(self):
f1 = Frame(self)
frm1 = Frame(f1)
self.lbl1 = Label(frm1, image=None)
setImageLabelFromFile(self.lbl1, '../image.bmp')
self.txt1 = Text(frm1, width=30, height=8)
sb1 = Scrollbar(frm1, orient='vertical', command=self.txt1.yview)
self.txt1.configure(yscrollcommand = sb1.set)
self.lbl1.pack()
self.txt1.pack(side='left')
sb1.pack(side='left', fill='y')
frm1.pack(side='left')
frm2 = Frame(f1)
self.lbl2 = Label(frm2, image=None)
setImageLabelFromFile(self.lbl2, '../image.bmp')
self.txt2 = Text(frm2, width=30, height=8)
sb2 = Scrollbar(frm2, orient='vertical', command=self.txt2.yview)
self.txt2.configure(yscrollcommand = sb2.set)
self.lbl2.pack()
self.txt2.pack(side='left')
sb2.pack(side='left', fill='y')
frm2.pack(side='left')
f1.pack()
f2 = Frame(self)
Button(f2, text='Run', command=self.run).pack(side='left')
Button(f2, text='Stop', command=self.stop).pack(side='left')
f2.pack()
def put_to_queue(self):
while self.isRunning:
self.ctr = self.ctr + 1
self.image = cv.QueryFrame(self.video)
time.sleep(1 / self.fps)
try:
writeToLog(self.txt1, '\nPut to queue .. %d' % (self.ctr))
temp1 = cv.CloneImage(self.image)
setImageLabelFromIplImage(self.lbl1, temp1)
temp2 = mat_from_ipl(temp1)
self.queue.put([self.ctr, temp2])
except:
writeToLog(self.txt1, '\nReach end of video ..')
break
def get_from_queue(self):
while self.isRunning:
from_queue = self.queue.get()
self.ctr_fr = from_queue[0]
if self.ctr_fr == self.ctr: time.sleep(30 / self.fps)
temp1 = ipl_from_mat(from_queue[1])
setImageLabelFromIplImage(self.lbl2, temp1)
writeToLog(self.txt2, '\nGet from queue .. %d' % (self.ctr_fr))
time.sleep(1 / self.fps)
def run(self):
self.isRunning = True
self.video = cv.CreateFileCapture('../video.avi')
self.fps = cv.GetCaptureProperty(self.video, cv.CV_CAP_PROP_FPS)
writeToLog(self.txt1, '\nStart put_queue ..')
self.putProc = threading.Thread(target=self.put_to_queue)
self.putProc.start()
time.sleep(1)
writeToLog(self.txt2, '\nStart get_queue ..')
self.getProc = threading.Thread(target=self.get_from_queue)
self.getProc.start()
def stop(self):
self.isRunning = False
if self.putProc.isAlive():
self.putProc._Thread__stop()
writeToLog(self.txt1, '\nputProc still alive, stopping ..')
self.putProc = None
if self.getProc.isAlive():
self.getProc._Thread__stop()
writeToLog(self.txt2, '\ngetProc still alive, stopping ..')
self.getProc = None
self.ctr_fr = 0
self.ctr = 0
if __name__ == '__main__':
root = Tk()
c = asdf(root)
root.mainloop()
Am I doing it wrong?
Any ideas will be very appreciated.
Thanks