2

I am building a device that counts how many parts are made off a machine and then turns the machine off at a specific number. I am using an Arduino for all the I/O work and then importing the serial data into Python as variable partCount. I would like to create a simple GUI in tkinter to show the number of parts that have been made and the total number needed. The problem is that I keep getting an error on the label lines that include a variable instead of just a text. I've done a lot of research on it, but I just can't get it for some reason. Any advice would be appreciated.

import serial
import csv
import datetime
import tkinter

#Part Variables
partNumber = "A-33693" #Part Number
stockupTotal = 10

arduinoSerialData = serial.Serial('com3',9600) #Serial Variable
now = datetime.datetime.now()

#GUI
window = tkinter.Tk()
window.title("Troy Screw Products")

titleLabel = tkinter.Label(window, text="Davenport Machine Control")
partNumberLabel = tkinter.Label(window, text="Part #:")
stockUpTotalLabel = tkinter.Label(window, text="Stockup Total:")
partCountLabel = tkinter.Label(window, text="Current Part Count:")
partNumberInfo = tkinter.Label(window, partNumber)
stockUpTotalInfo = tkinter.Label(window, stockupTotal)
partCountInfo = tkinter.Label(window, partCount)


titleLabel.pack()
partNumberLabel.pack()
partNumberInfo.pack()
stockUpTotalLabel.pack()
stockUpTotalInfo.pack()
partCountLabel.pack()
partCountInfo.pack()

window.mainloop()


#Write to CSV File
def writeCsv():
    with open("machineRunData.csv", "a") as machineData: 
        machineDataWriter = csv.writer(machineData) 
        machineDataWriter.writerow([partNumber, "Stockup Complete",now.strftime("%Y-%m-%d %H:%M")])
        machineData.close()

#Serial Import
while (1==1):
    if (arduinoSerialData.inWaiting()>0):
        partCount = arduinoSerialData.readline()
        partCount = int(partCount)
        if partCount == 999999:
             writeCsv()
        print(partCount)
shark38j
  • 114
  • 13

2 Answers2

0

There are several options you can give to a Label widget, as you can see here. You should specify all parameters after the first by name:

partNumberInfo = tkinter.Label(window, text=PartNumber)

To use Python variables in Tkinter you need to special Tk objects, of which there are four: BooleanVar, DoubleVar, IntVar, and StringVar. See this answer for a good example.

Community
  • 1
  • 1
Ethan Furman
  • 63,992
  • 20
  • 159
  • 237
  • Adding "text=" before the variable got all the information onto the window. The only remaining problem I have is that I want the number in the window to change as the variable changes in my program. It just stays at zero at the moment. I somehow need to get the variable in the tkinter window to update when it updates in python – shark38j Feb 02 '16 at 18:54
  • @shark38j: Updated answer. – Ethan Furman Feb 02 '16 at 19:00
  • 1
    @shark38j You can use the textvariable option with a StringVar as Ethan suggested and as shown in the linked answer. Or you can use the text option and update with `partNumberInfo['text'] = int_as_string`. Don't use both options. – Terry Jan Reedy Feb 02 '16 at 23:35
0

So after a ton of research over the last week, I found a solution. The problem was that the program would run the GUI, but not run the code for the serial import until the GUI window was closed. I needed a way to get both the GUI running and updated and get the serial data importing at the same time. I resolved this by creating a thread for both operations. There's probably an easier way to do this, but this what I came up with. The code is below for anyone having a similar problem.

import serial
import time
import threading
from tkinter import *

#Part Variables
partNumber = "A-33693" #Part Number
stockupTotal = 10

partCount = 0

def countingModule():
    global partCount
    while (1==1):
        time.sleep(2)
        partCount += 1
        print(partCount)


def gui():
    global partCount
    root = Tk()

    pc = IntVar()
    pc.set(partCount)

    titleLabel = Label(root, text="Machine Control")
    partNumberLabel = Label(root, text="Part #:")
    stockUpTotalLabel = Label(root, text="Stockup Total:")
    partCountLabel = Label(root, text="Current Part Count:")
    partNumberInfo = Label(root, text=partNumber)
    stockUpTotalInfo = Label(root, text=stockupTotal)
    partCountInfo = Label(root, textvariable=pc)


    titleLabel.pack()
    partNumberLabel.pack()
    partNumberInfo.pack()
    stockUpTotalLabel.pack()
    stockUpTotalInfo.pack()
    partCountLabel.pack()
    partCountInfo.pack()

    def updateCount():
        pc.set(partCount)
        root.after(1, updateCount)

    root.after(1, updateCount)
    root.mainloop()

op1 = threading.Thread(target = countingModule)
op2 = threading.Thread(target = gui)
op1.start()
op2.start()
shark38j
  • 114
  • 13