Working with tempfiles

Hello good morning ,I am learning how to use temporary files to save and load information in an application and I am experiencing problems when loading the information for the second time when I open Qdialog Win1 with out close the app,could you help me?

from PySide6.QtWidgets import QApplication,QMainWindow,QPushButton,QSpinBox,QDialog,QDialogButtonBox,QFormLayout
import tempfile,ast

import sys

app=QApplication(sys.argv)

data={'num1':2,'num2':4}

class Ventana_Principal(QMainWindow):
    def __init__(self):
        super().__init__()

        self.setFixedSize(400,200)
        self.initUi()
        self.create_temp_file()

    def initUi(self):

        self.button1=QPushButton()
        self.button1.clicked.connect(self.first_wnd)
        self.setCentralWidget(self.button1)

    def create_temp_file(self):
     
     self.data=str(data)
     
     self.temporary_file=tempfile.TemporaryFile('w+')
     self.temporary_file.write(self.data)

   
    def first_wnd(self):
       
       window1=Win1(self.temporary_file)       

    def closeEvent(self, event):
       self.temporary_file.close()
       


class Win1(QDialog):
   def __init__(self,temp_file):
      super().__init__()

      self.setFixedSize(180,120)
      self.temporary_file=temp_file

      self.qspin1=QSpinBox()
      self.qspin1.setFixedSize(50,25)

      self.qspin2=QSpinBox()
      self.qspin2.setFixedSize(50,25)

      self.layout1=QFormLayout(self)
      self.layout1.setHorizontalSpacing(20)
      self.layout1.setVerticalSpacing(50)
   
      #self.layout1.setContentsMargins(0,0,13)

      self.botones=QDialogButtonBox()
      #self.botones.setGeometry(100,20,50,25)
      self.botones=QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
      self.botones.accepted.connect(self.update_data)
      self.botones.rejected.connect(self.cancelar)  

      self.layout1.addRow(self.qspin1,self.qspin2)
      self.layout1.addRow(self.botones)  

      self.load_data()

      self.exec()

   def load_data(self):
      
      self.temporary_file.seek(0)
      self.data_back=ast.literal_eval(self.temporary_file.read())
      
      

      self.qspin1.setValue(float(self.data_back['num1']))
      self.qspin2.setValue(float(self.data_back['num2']))
      print(self.data_back)

   def update_data(self):

      
      self.data_back['num1']=self.qspin1.value()
      self.data_back['num2']=self.qspin2.value()

   
      self.data_in=str(self.data_back)
      
      self.temporary_file.write(self.data_in)
      

      self.accept()  


    
   def cancelar(self):  
       self.reject()  




wnd=Ventana_Principal()

wnd.show()
 
app.exec()

Hello @Damian,

The second time you write in the file it breaks the format and cause a syntax error when loading the file content using ast.literal_eval.

file content after first write:
{'num1': 2, 'num2': 4}

After second write:
{'num1': 2, 'num2': 4}{'num1': 4, 'num2': 6}

As you can see this is not valid python code so it raises an exception when it’s evaluated.

What you can do is to remove the content of the file before to write in it:

    def update_data(self):

        self.data_back['num1']=self.qspin1.value()
        self.data_back['num2']=self.qspin2.value()

        self.data_in=str(self.data_back)
        self.temporary_file.seek(0)
        self.temporary_file.truncate()
        self.temporary_file.write(self.data_in)
        self.accept()

If you want to keep the history of all the values, you need to add a comma (,) between your records, then you have to read it as a list.

    def load_data(self):

        self.temporary_file.seek(0)
        self.data_back=ast.literal_eval(self.temporary_file.read())
        if isinstance(self.data_back, (list, tuple)):
            # get the latest dictionary from the list
            self.data_back = self.data_back[-1]

        self.qspin1.setValue(float(self.data_back['num1']))
        self.qspin2.setValue(float(self.data_back['num2']))
        print(self.data_back)

    def update_data(self):

        self.data_back['num1']=self.qspin1.value()
        self.data_back['num2']=self.qspin2.value()

        self.data_in=str(self.data_back)
        # Not sure if that's the best way to check if file is not empty
        if self.temporary_file.seekable():
            self.temporary_file.write(',')
    
        self.temporary_file.write(self.data_in)
        self.accept()

thank you very much @ros ,problem solve :grinning:

Dont appear the solve button

I know this was already solved for you, but for future temporary file needs, I’d suggest taking a look at QTemporaryFile to see if it can simplify your temp file handling tasks.