Filedialog

Fragen zu Tkinter.
Antworten
Kieste_95
User
Beiträge: 1
Registriert: Dienstag 25. April 2023, 15:00

Hallo zusammen,

ich bin kompletter Anfänger, was das Thema Python angeht.
Ich arbeite als CAM-Programmierer, wobei ich viel mit CNC Code zu tun habe.
Nun möchte ich mir, um den Arbeitstag zu erleichtern, ein kleines Programm schreiben, mit dem ich Dateien Splitten kann.
Also eine .txt Datei anhand von bestimmen Zeilen in der Dateien in mehrere Dateien zu splitten.
Ich hangele mich jetzt von "Wie erstelle ich eine GUI" zu "Wie öffne ich eine Datei".

Aktuell möchte eine Datei über einen filedialog auswählen und diese dann in Notepad öffnen.
Das ganze funktioniert aber irgendwie nicht so, kann mir dort einer helfen?

Hier mal der Code:

import customtkinter
from tkinter import *
from customtkinter import filedialog
import os
import subprocess

customtkinter.set_appearance_mode("Dark")
customtkinter.set_default_color_theme("dark-blue")

window = customtkinter.CTk()
window.geometry("350x200")
window.title("File Spiltter")

def file_select():
window.filename = filedialog.askopenfilename(initialdir="\Desktop",title="Select a file", filetypes=(("All files","*.*"),("Arc files","*.arc")))
print(window.filename)
subprocess.Popen("notepad.exe",window.filename)

frame = customtkinter.CTkFrame(master=window,border_width=2,corner_radius=30)
frame.pack(padx=20,pady=20,fill="both", expand=True)

label = customtkinter.CTkLabel(master=frame, text="Select a file to open")
label.pack(padx=20, pady=15)

button = customtkinter.CTkButton(master=frame, text="Select a file",command=file_select)
button.pack(pady=15)

window.mainloop()


Gruß
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Kieste_95: Wenn Du das in einer Konsole startest, dann siehst Du die Ausnahme von dem `Popen()`-Aufruf. Das was gestartet werden soll ist das *erste* Argument, in Form einer Liste (oder allgemein Sequenz). Das zweite Argument ist eine Puffergrösse und die muss eine ganze Zahl sein. Wenn man sie denn überhaupt angeben möchte.

Weitere Anmerkungen: `os` wird importiert, aber nirgends verwendet. Und *alles* aus `tkinter` wird per Sternchen importiert. Das macht man sowieso schon nicht so, aber wenn man dann zusätzlich *nichts* davon verwendet, ist das auch noch sinnlos.

Im Fenstertitel ist ein Buchstabendreher.

Auf Modulebene sollte nur Code stehen, der Konstanten, Funktionen, und Klassen definiert. Das Hauptrogramm steht üblicherweise in einer Funktion die `main()` heisst.

Die Fenstergrösse sollte man nicht vorgeben, die ergibt sich automatisch durch den Fensterinhalt. Dann kann man auch sicher sein, dass beides zusammen passt und nicht Anzeigeelemente nicht mehr in den sichtbaren Teil passen und damit für den Benutzer nicht mehr sichtbar/bedienbar sind.

Wenn es für eine Zeichenkette mit besonderer Bedeutung eine Konstante im `customtkinter`-Modul gibt, sollte man die benutzen.

Da es das globale `window` nicht geben darf, kann `file_select()` da auch nicht einfach so drauf zugreifen. Es macht aber auch nicht wirklich Sinn den ausgewählten Dateinamen dort dran zu binden. Wenn man etwas über Aufrufe hinweg behalten möchte, sollte man nicht einfach irgendwelche vorhandenen Objekte durch neue Attribute erweitern, sondern eine eigene Klasse schreiben. Sonst wird es schnell unübersichtlich und man läuft Gefahr schon vorhandene Attribute zu überschreiben.

Der Code berücksichtigt nicht, dass der Benutzer statt einen Dateinamen auszuwählen, auch einfach das Fenster schliessen oder Abbrechen/Cancel auswählen kann.

Es ist unsauber einfach so Prozesse zu starten und das `Popen`-Objekt zu verwerfen ohne den Exit-Status abzufragen. So können Zombieprozesse entstehen, die Systemressourcen belegen.

Zwischenstand (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
import subprocess
from threading import Thread

import customtkinter as ctk
from customtkinter import filedialog


def wait_for_process(process):
    process.wait()


def file_select():
    filename = filedialog.askopenfilename(
        initialdir=R"\Desktop",
        title="Select a file",
        filetypes=(("All files", "*.*"), ("Arc files", "*.arc")),
    )
    print(filename)
    if filename:
        Thread(
            target=Popen(["notepad.exe", filename]).wait, daemon=True
        ).start()


def main():
    ctk.set_appearance_mode("Dark")
    ctk.set_default_color_theme("dark-blue")

    window = ctk.CTk()
    window.title("File Splitter")

    frame = ctk.CTkFrame(window, border_width=2, corner_radius=30)
    frame.pack(padx=20, pady=20, fill=ctk.BOTH, expand=True)

    ctk.CTkLabel(frame, text="Select a file to open").pack(padx=20, pady=15)
    ctk.CTkButton(frame, text="Select a file", command=file_select).pack(
        pady=15
    )

    window.mainloop()


if __name__ == "__main__":
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten