0

EDIT: Yes, I have a similar problem as the link below but I don’t think this is a duplicate question because unfortunately, the answer doesn’t solve my problem. How come a file doesn't get written until I stop the program?

I tried the f=open(file,w) f.close() f.flush() os.fsync(f) and it didn’t help. Please also note that I am using with statement that should accomplish the same thing as once the Python exits from the with block, the file is automatically closed.

Even all that the file still doesn’t get written until I close the program.

I also noticed now that this is not a Tkinter problem as I thought first, the problem exist without the Tkinter GUI. Might be something to do with the lxml.etree

ORIGINAL QUESTION BELOW

I have tried to make a simple GUI for the XML converter script.

I am having problems when saving the file. The file doesn’t get written until I close or destroy() the Tkinter program. Can anyone explain why that would happen and how to fix it? I would like to write the file while the Tkinter window is running.

Please find below the code:

from tkinter import *
import lxml.etree as ET
import tkinter.filedialog as fdialog

def mfileopen():
    global xml_file
    xml_file = fdialog.askopenfile()
    Label(text=xml_file) .pack()

def dropdown_select(selection):
    global xslt_file
    if selection == "Stylesheet 1":
        xslt_file = "stylesheet1.xsl"

    elif selection == "Stylesheet 2":
        xslt_file = "stylesheet2.xsl"

def convert_xml(xslt_file, input_xml):
    dom = ET.parse(input_xml)
    xslt = ET.parse(xslt_file)
    transform = ET.XSLT(xslt)
    newdom = transform(dom)
    write_file(newdom)

def write_file(csv_file):
    with open("output.csv", "w") as f:
        f.write(str(csv_file))

OPTIONS = [
"Stylesheet 1",
"Stylesheet 2",
]

master = Tk()

Label (text="Open XML file and then Choose XSLT Code from the dorpdown menu and press Load XSLT. Finally press Convert XML") .pack()

button = Button(text="Open XML File", width=30, command=mfileopen)
button.pack()

variable = StringVar(master)
variable.set(OPTIONS[0]) # default value

w = OptionMenu(master, variable, *OPTIONS)
w.pack()

button = Button(master, text="Load XSLT", command=lambda: dropdown_select(variable.get()))
button.pack()

button = Button(master, text="Convert XML", command=lambda: convert_xml(xslt_file, xml_file))
button.pack()

master.mainloop()
Tim
  • 75
  • 1
  • 8
  • 1
    Welcome to StackOverflow. Please read and follow the posting guidelines in the help documentation, as suggested when you created this account. [Minimal, complete, verifiable example](https://stackoverflow.com/help/minimal-reproducible-example) applies here. This code has plenty of superfluous lines. – Prune Jun 20 '19 at 20:27
  • 1
    Also be careful with globals. Its possible `xslt_file` and `xml_file` don't exist when `convert_xml(xslt_file, xml_file)` is called. – Error - Syntactical Remorse Jun 20 '19 at 20:29
  • 2
    In the meantime, try tracing the execution: insert a parallel `print` statement to dump the lines as you write to the file. My suspicion is that you simply haven't filled up the buffer. Try a `flush` on the output stream as you write. – Prune Jun 20 '19 at 20:29
  • @Prune Thank you for your suggestion. `Print` works fine, prints everything as it should, I tried the f.flush() and unfortunately, it didn’t help. Please also note that I am using `with` statement that should accomplish the same thing as once the Python exits from the `with` block, the file is automatically closed. – Tim Jun 22 '19 at 13:25
  • @Error - Syntactical Remorse Thank you for pointing out the globals but that's not the problem in this case. – Tim Jun 22 '19 at 13:30
  • Sorry for the trouble everyone, I found out the issue. There was actually nothing wrong with the original script, it actually works as it should, even without the flush(). I am using macOS PyCharm and the issue was the PyCharm project folder refresh. The actual file gets written to the disk immediately but as I was looking the PyCharm project folder window that didn’t update until you actually click somewhere in the PyCharm window or when the program stops. Should I just delete this question as it’s actually misleading or edit the question? – Tim Jun 22 '19 at 17:35

1 Answers1

1

You need to f.close() to flush the file write buffer out to the file. Or in your case you might just want to do a f.flush(); os.fsync(); so you can keep looping with the opened file handle.

Don't forget to import os.

For more information: How come a file doesn't get written until I stop the program?

  • Thank you for your suggestion. I tried the `f=open(file,w)` `f.close()` `f.flush()` `os.fsync(f)` and unfortuantelly it didn’t help. – Tim Jun 22 '19 at 13:21
  • @Tim Add the `f.flush()` RIGHT after you write to it. (Inside the `open` statement. Also you don't need a `f.close()` because you have the `with` statement. – Error - Syntactical Remorse Jun 22 '19 at 14:42