Page 1 of 1

Tkinter GUI saving textfile

Posted: Fri Sep 06, 2019 10:22 am
by timothyy
I'm trying to make a toggle button to save a text file in Tkinter, and this is my last bit of code. I've defined toggle7, writetotxtfile and ADClogall, but saving a text file with no success. Any suggestion?

Code: Select all

def toggle7():
    if var7.get() == "Saving...":
        writetotxtfile()
        ADClogall("text1.txt")
    
var7 = tk.StringVar()
toggle = tk.Checkbutton(root, onvalue="Saving...", offvalue="Save to file", width=4,
                        indicatoron=False, 
                        variable=var7, textvariable=var7,
                        command=toggle7)
var6.set("Save to file")
toggle.place(x=220, y=210)

def writetotxtfile(texttowrite,filename):
    file = open(str(filename), 'a')
    file.write(str(datetime.datetime.now()) + " " + str(texttowrite) + '\n')
    file.close()


def ADClogall(filename):
    adc1 = ADCPi(0x68,0x69,12)
    adc2 = ADCPi(0x6A,0x6B,12)
    
    columntitle = ['chn1','chn2','chn3','chn4','chn5','chn6','chn7','chn8','chn9','chn10','chn11','chn12','chn13','chn14','chn15','chn16']
    writetotxtfile(columntitle,filename)
    while True:
        all8chn = [adc1.read_voltage(1), adc1.read_voltage(2), adc1.read_voltage(3), adc1.read_voltage(4), adc1.read_voltage(5), adc1.read_voltage(6), adc1.read_voltage(7), adc1.read_voltage(8),adc2.read_voltage(1), adc2.read_voltage(2), adc2.read_voltage(3), adc2.read_voltage(4), adc2.read_voltage(5), adc2.read_voltage(6), adc2.read_voltage(7), adc2.read_voltage(8)]
        writetotxtfile(all8chn, filename)
        root.after(1000,ADClogall)
        
mainloop()

Re: Tkinter GUI saving textfile

Posted: Fri Sep 06, 2019 10:52 am
by scotty101
As you haven't provided a complete example of your code, I've had to invent a lot of stuff to guess what you are trying to do in order to produce this example for you.

Code: Select all

from tkinter import *
import tkinter as tk
import time
import datetime

    
def writetotxtfile(texttowrite,filename):
    file = open(str(filename), 'a')
    file.write(str(datetime.datetime.now()) + " " + str(texttowrite) + '\n')
    file.close()

def getADCData():
    """Dummy function to return ADC data"""
    return "Hello World"

def logData():
    if var7.get() == "Saving...":
        writetotxtfile(getADCData(), 'text1.txt')
        print('Writing to file')
    root.after(1000,logData)

root = tk.Tk()
var7 = tk.StringVar(root)
var7.set('Save to file')
toggle = tk.Checkbutton(root,
                        onvalue="Saving...",
                        offvalue="Save to file",
                        indicatoron=False, 
                        variable=var7,
                        textvariable=var7)


toggle.grid()
root.after(1000, logData)
root.mainloop()
Every second this will check to see if the toggle button is still set to on. If it is, it will read the data from the ADC (i have a dummy function here), and write it to a file along with the date/time stamp.

You must NEVER use a "while True" loop inside a tkinter program. It will crash the GUI.

Also, since you open and close the file each time, you are likely to need to add some code to check whether the log file exists or not. If it doesn't exist you should open it, write the column headers and then save it again.

Your current function to read the ADCs, initialises them each time. This will slow down the read as you usually have to wait some time after initialising them before getting the first reading. Initialise the ADCs once at the start of the program and just read them in your "readADC" function.

Re: Tkinter GUI saving textfile

Posted: Thu Sep 12, 2019 11:55 am
by timothyy
Hi, I have changed my code according to the example.

Code: Select all

def writetotxtfile(texttowrite,filename):
    file = open(str(filename), 'a')
    file.write(str(datetime.datetime.now()) + " " + str(texttowrite) + '\n')
    file.close()


def ADClogall():
    adc1 = ADCPi(0x68,0x69,12)
    adc2 = ADCPi(0x6A,0x6B,12)
    all8chn = [adc1.read_voltage(1), adc1.read_voltage(2), adc1.read_voltage(3), adc1.read_voltage(4), adc1.read_voltage(5), adc1.read_voltage(6), adc1.read_voltage(7), adc1.read_voltage(8),adc2.read_voltage(1), adc2.read_voltage(2), adc2.read_voltage(3), adc2.read_voltage(4), adc2.read_voltage(5), adc2.read_voltage(6), adc2.read_voltage(7), adc2.read_voltage(8)]

def toggle7():
    if var7.get() == "Saving...":
        writetotxtfile(ADClogall(),"text1.txt")
    root.after(1000, toggle7) 
    
var7 = tk.StringVar()
toggle = tk.Checkbutton(root, onvalue="Saving...", offvalue="Save to file", width=4,
                        indicatoron=False, 
                        variable=var7, textvariable=var7)

var7.set("Save to file")
toggle.place(x=220, y=210)
 
root.after(1000, toggle7)       
mainloop()
The function works successfully, however there maybe a problem when logging all the data from all8chn. It shows the following output in the text file instead. Is there a problem in the function when defining the ADClogall()?

Code: Select all

2019-09-12 11:52:11 <fuction ADClogall at 0x75fe0e88>

Re: Tkinter GUI saving textfile

Posted: Thu Sep 12, 2019 12:07 pm
by scotty101
Function ADClogall doesn't return anything.

Try

Code: Select all

def ADClogall():
    adc1 = ADCPi(0x68,0x69,12)
    adc2 = ADCPi(0x6A,0x6B,12)
    all8chn = [adc1.read_voltage(1), adc1.read_voltage(2), adc1.read_voltage(3), adc1.read_voltage(4), adc1.read_voltage(5), adc1.read_voltage(6), adc1.read_voltage(7), adc1.read_voltage(8),adc2.read_voltage(1), adc2.read_voltage(2), adc2.read_voltage(3), adc2.read_voltage(4), adc2.read_voltage(5), adc2.read_voltage(6), adc2.read_voltage(7), adc2.read_voltage(8)]
    return all8chn

Re: Tkinter GUI saving textfile

Posted: Mon Sep 16, 2019 11:19 am
by timothyy
I have tried this function, but still got the same problem. Is there any way that can make the RasPi read the values?

Code: Select all

def ADClogall():
    adc1 = ADCPi(0x68,0x69,12)
    adc2 = ADCPi(0x6A,0x6B,12)
    all8chn = [adc1.read_voltage(1), adc1.read_voltage(2), adc1.read_voltage(3), adc1.read_voltage(4), adc1.read_voltage(5), adc1.read_voltage(6), adc1.read_voltage(7), adc1.read_voltage(8),adc2.read_voltage(1), adc2.read_voltage(2), adc2.read_voltage(3), adc2.read_voltage(4), adc2.read_voltage(5), adc2.read_voltage(6), adc2.read_voltage(7), adc2.read_voltage(8)]
    return all8chn