Seite 1 von 1

File editor

Verfasst: Sonntag 17. Januar 2021, 11:11
von rennmaus
Hallo,
Vorab möchte ich angemerkt haben, dass ich Python jetzt seit etwa 4-5 Monaten mache, also wird mir der ein oder andere Fehler unterlaufen sein.

Ich habe mir einen kleinen File Editor programmiert (in tkinter, was ich auch toll finde :D ), womit ich:
1.: Bilder in andere Dateiformate konvertieren kann.
2.: Pdf's verschlüsseln kann.
3.: Pdf's verbinden kann (in einer Benutzerdefinierten Reihenfolge.
Ich bin sehr zufrieden damit, da es auch gut funktioniert. Was ich auch cool finde ist, dass man das Programm von überall starten kann, aber es funktioniert trotzdem immer. Ich freue mich über Feedback!

Code: Alles auswählen

import os, tkinter, sys
from PyPDF2 import PdfFileReader, PdfFileWriter
from tkinter import filedialog, messagebox
import os.path
from PIL import Image
import comtypes
from comtypes.client import CreateObject
from comtypes.persist import IPersistFile
from comtypes.shelllink import ShellLink

def pdf_1():

    pdf_writer=PdfFileWriter()
    app=tkinter.Tk()
    app.title("Pdf editor")
    app.geometry("400x220")

    def add_files():
        box.delete('0', 'end')
        files = tkinter.filedialog.askopenfilenames(parent=app, title='Bitte PDFs auswählen',
                                                    filetypes=[("PDF", ".pdf")])
        for file in files:
            box.insert('end', file)
        return files

    def merge(name='mergedPDF'):
        work=workflow.get()
        if work==0:
            files=box.get('0', 'end')
            for file in app.tk.splitlist(files):
                pdf_reader=PdfFileReader(file)
                for page in range(pdf_reader.getNumPages()):
                    pdf_writer.addPage(pdf_reader.getPage(page))
            bilder = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Pictures')
            bilder += "/converted_files/"
            with open(bilder+name+".pdf", 'wb') as out:
                pdf_writer.write(out)
                messagebox.showinfo(title="Erfolgreich", message="Dateien erfolgreich verbunden")

        if work==1:
            files=box.get('0', 'end')
            files=app.tk.splitlist(files)
            e=ein.get()
            e=e.split("-")
            for num in e:
                num=int(num)
                pdf_reader=PdfFileReader(files[num-1])
                for page in range(pdf_reader.getNumPages()):
                    pdf_writer.addPage(pdf_reader.getPage(page))

            bilder = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Pictures')
            bilder += "/converted_files/"
            with open(bilder + name + ".pdf", 'wb') as out:
                pdf_writer.write(out)
                messagebox.showinfo(title="Erfolgreich", message="Dateien erfolgreich verbunden")

    def encrypt_pdf():

        def get():
            password = e.get()
            for file in app.tk.splitlist(nam):
                pdf_reader = PdfFileReader(file)
                pdf_writer = PdfFileWriter()
                for page in range(pdf_reader.getNumPages()):
                    pdf_writer.addPage(pdf_reader.getPage(page))
                pdf_writer.encrypt(user_pwd=password, use_128bit=True)
                bilder = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Pictures')
                bilder += "/converted_files/"
                with open(bilder+file.split("/")[-1]+"-verschlüsselt.pdf", "wb") as out:
                    pdf_writer.write(out)
            messagebox.showinfo(title="Erfolgreich", message="Die verschlüsselung war erfolgreich!")

        nam = box.get('0', 'end')
        eingabefeld_wert = tkinter.StringVar()
        e = tkinter.Entry(app, textvariable=eingabefeld_wert)
        e.place(x=100, y=0)
        tkinter.Button(app, text="confirm", command=get).place(x=100, y=20)


    def beenden():
        app.destroy()

    tkinter.Button(app, text="add files", command=add_files).grid()
    tkinter.Button(app, text="verbinden", command=merge).grid()
    tkinter.Button(app, text="verschlüsseln", command=encrypt_pdf).grid()
    tkinter.Button(app, text="beenden", command=beenden).grid()
    box=tkinter.Listbox(app, selectmode='browse')
    box.place(width=400, height=80, y=100)
    workflow = tkinter.IntVar()
    workflow.set(0)
    tkinter.Checkbutton(app, variable=workflow, onvalue=1, offvalue=0).place(x=0, y=200)
    workflow.set(1)
    ein=tkinter.Entry(app)
    ein.place(x=20, y=200)
    app.mainloop()


def pic():
    applic = tkinter.Tk()
    applic.title("File converter")
    bilder = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Pictures')
    bilder+="/converted_files"

    listboxfile = tkinter.Listbox(applic, selectmode='browse')
    listboxfile.place(x=100, y=250, width=250, height=100)
    types= r" *.png  *.tiff  *.gif  *.jpg  *.ico"

    def new_img():
        input = tkinter.filedialog.askopenfilenames(parent=applic, title="Dateien auswählen", filetypes=[("Bilder:", types)])
        listboxfile.delete('0', 'end')
        for file in applic.tk.splitlist(input):
            listboxfile.insert('end', file)
        return input

    def add_img():
        input = tkinter.filedialog.askopenfilenames(parent=applic, title="Dateien auswählen", filetypes=[("Bilder:", types)])
        for file in applic.tk.splitlist(input):
            listboxfile.insert('end', file)

    applic.geometry("350x350")
    Options=['.png', '.tiff', '.pdf', '.gif', '.TIF', '.ico', '.jpg']
    variable = tkinter.StringVar(applic)
    variable.set(Options[0])
    opt = tkinter.OptionMenu(applic, variable, *Options)
    opt.config(width=90, font=('Helvetica', 12))
    opt.pack()

    def conv():
        messagebox.showwarning(title='Wichtig!', message='Dateien gleicher Endung werden überschrieben!!')
        input = listboxfile.get('0', 'end')
        i=0
        puffer = os.path.dirname(os.path.abspath(sys.argv[0]))
        for file in applic.tk.splitlist(input):
            try:
                os.remove(puffer+"/conv.gif")
            except:
                pass
            f=bilder
            _, e = os.path.splitext(file)
            i+=1
            im = Image.open(file)
            output = f+"/_"+str(i)+variable.get()

            if e == '.tiff' or e == '.png' or e == '.TIF':
                im.save(puffer + '/conv.gif')
                im = Image.open(puffer + '/conv.gif')
            if im.mode != 'RGB' and variable.get() == '.jpg':
                im = im.convert('RGB')
            if variable.get() == '.jpg':
                im.save(output, "JPEG")

            else:
                pass
            im.save(output)

        if check == 1:
            listboxfile.delete('0', 'end')

        else:
            pass

        messagebox.showinfo(title="Konvertierung erfolgreich", message="Konvertierung erfolgreich!")
    but=tkinter.Button(applic, text="select new files", command=new_img)
    but.place(y=300)
    but.pack()
    tkinter.Button(applic, text="select more files", command=add_img).pack()
    tkinter.Button(applic, text="convert", command=conv).pack()
    check = tkinter.IntVar()
    tkinter.Checkbutton(applic, text="Dateiliste danach verwerfen", variable=check, onvalue=1, offvalue=0).place(y=210, x=100)
    check.set(1)

    def beende():
        applic.destroy()
    tkinter.Button(applic, text="beenden", command=beende).pack()
    applic.mainloop()

def main():
    desktop = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Desktop')
    bilder = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Pictures')
    def create_folder():

        os.makedirs(bilder+"\\converted_files")

    def create_shortcut():
        datei = os.path.abspath(sys.argv[0])

        s = CreateObject(ShellLink)
        s.SetPath(datei)

        p = s.QueryInterface(IPersistFile)
        p.Save(desktop + "\\File editor.lnk", True)

        s = CreateObject(ShellLink)
        p = s.QueryInterface(IPersistFile)
        p.Load(desktop + "\\File editor.lnk", True)

    def pdf():
        pdf_1()
    def cov():
        pic()


    var1=os.path.isdir(bilder+"\\converted_files")

    if var1 is not True:
        create_folder()

    root=tkinter.Tk()
    root.title("File editor")
    tkinter.Label(root, text="Was möchtest du machen?").pack()
    tkinter.Button(root, text="Pdf editor", command=pdf).pack()
    tkinter.Button(root, text="Picture convert", command=cov).pack()
    tkinter.Button(root, text="Create shortcut", command=create_shortcut).pack()
    root.mainloop()

if __name__ == '__main__':
    main()
ps: Ich weiß, es wäre besser .grid als .place zu verwenden, aber ich hatte den Code schon so geschrieben und hatte keine Lust in nochmal umzuschreiben. Der Code wird aber von mir immer weiterentwickelt, deshalb werde ich wahrscheinlich irgendwann mal .grid für alle verwenden, wann das sein wird, kann ich noch nicht sagen :wink:

Mfg
Christian

Re: File editor

Verfasst: Sonntag 17. Januar 2021, 11:36
von nezzcarth
Da sind eine Reihe von Sachen, die auffallen. Was aber wirklich ins Auge sticht, ist deine Verwendung von "Funktionen". Funktionen sind als kleine, abgeschlossene, wiederverwendbare und für sich stehende Einheiten gedacht, die in den meisten Fällen einen Rückgabewert haben sollten. Closures (Funktionen in Funktionen) verwendet man für konkrete eingegrenzte Anwendungszwecke (zum Beispiel zur Implementierung von Dekoratoren). Du verwendest Funktionen jedoch eher als "Stil-Element" zur Gliederung von Code, als Namespaces oder als Aliase. Das ist sehr ungewöhnlich und so nicht gedacht. Wenn du zusammengehörige Funktionalitäten modellieren möchtest, ist das OOP das Mittel der Wahl, und für sinnvolle GUI-Programmierung eigentlich auch eine Voraussetzung. Vieles, was ich da beim Überfliegen gesehen habe, könnten aber auch einfach reguläre Funktionen auf Modulebene sein, die nicht "versteckt" werden müssen.

Re: File editor

Verfasst: Sonntag 17. Januar 2021, 11:53
von Sirius3
Es darf nur ein Exemplar von Tk im gesamten Programm geben. Weitere Fenster macht man mit TopLevel. Funktionen dürfen nicht innerhalb von Funktionen definiert sein, weil das das Programm undurchsichtig und untestbar macht, genauso wie die globalen Variablen, die Du überall benutzt.
Das nächste ist, dass Du Pfade mit + zusammenstückelst, obwohl Du es doch besser weist, und an anderen Stellen os.path.join benutzt.

Re: File editor

Verfasst: Sonntag 17. Januar 2021, 13:13
von rennmaus
Ok, danke für euer Feedback, ich werde versuchen es zu verarbeiten. Einen schönen Sonntag noch!

Re: File editor

Verfasst: Sonntag 17. Januar 2021, 13:17
von __blackjack__
Schlechte Namen fallen auch auf den ersten Blick auf. Kryptische Abkürzungen bis hin zu einbuchstabigen Namen und nummerierte Namen. Mindestens ein `Options` habe ich gesehen das kleingeschrieben werden sollte.

Re: File editor

Verfasst: Sonntag 17. Januar 2021, 14:33
von rennmaus

Code: Alles auswählen

import os, tkinter, sys
from PyPDF2 import PdfFileReader, PdfFileWriter
from tkinter import filedialog, messagebox
import os.path
from PIL import Image
import comtypes
from comtypes.client import CreateObject
from comtypes.persist import IPersistFile
from comtypes.shelllink import ShellLink

root=tkinter.Tk()


def pdf_1():

    pdf_writer=PdfFileWriter()
    app=tkinter.Toplevel(root)
    app.title("Pdf editor")
    app.geometry("400x220")

    def add_files():
        box.delete('0', 'end')
        files = tkinter.filedialog.askopenfilenames(parent=app, title='Bitte PDFs auswählen',
                                                    filetypes=[("PDF", ".pdf")])
        for file in files:
            box.insert('end', file)
        return files

    def merge(name='mergedPDF'):
        work=workflow.get()
        if work==0:
            files=box.get('0', 'end')
            for file in app.tk.splitlist(files):
                pdf_reader=PdfFileReader(file)
                for page in range(pdf_reader.getNumPages()):
                    pdf_writer.addPage(pdf_reader.getPage(page))
            bilder = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Pictures')
            bilder = os.path.join(bilder, "converted_files")
            with open(os.path.join(bilder, name + ".pdf"), 'wb') as out:
                pdf_writer.write(out)
                messagebox.showinfo(title="Erfolgreich", message="Dateien erfolgreich verbunden")

        if work==1:
            files=box.get('0', 'end')
            files=app.tk.splitlist(files)
            e=ein.get()
            e=e.split("-")
            for num in e:
                num=int(num)
                pdf_reader=PdfFileReader(files[num-1])
                for page in range(pdf_reader.getNumPages()):
                    pdf_writer.addPage(pdf_reader.getPage(page))

            bilder = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Pictures')
            bilder = os.path.join(bilder, "converted_files")
            with open(os.path.join(bilder, name + ".pdf"), 'wb') as out:
                pdf_writer.write(out)
                messagebox.showinfo(title="Erfolgreich", message="Dateien erfolgreich verbunden")

    def encrypt_pdf():

        def get():
            password = e.get()
            for file in app.tk.splitlist(nam):
                pdf_reader = PdfFileReader(file)
                pdf_writer = PdfFileWriter()
                for page in range(pdf_reader.getNumPages()):
                    pdf_writer.addPage(pdf_reader.getPage(page))
                pdf_writer.encrypt(user_pwd=password, use_128bit=True)
                bilder = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Pictures')
                bilder = os.path.join(bilder, "converted_files")
                with open(os.path.join(bilder, file.split("/")[-1]+"-verschlüsselt.pdf"), "wb") as out:
                    pdf_writer.write(out)
            messagebox.showinfo(title="Erfolgreich", message="Die verschlüsselung war erfolgreich!")

        nam = box.get('0', 'end')
        eingabefeld_wert = tkinter.StringVar()
        e = tkinter.Entry(app, textvariable=eingabefeld_wert)
        e.place(x=100, y=0)
        tkinter.Button(app, text="confirm", command=get).place(x=100, y=20)


    def beenden():
        app.destroy()

    tkinter.Button(app, text="add files", command=add_files).grid()
    tkinter.Button(app, text="verbinden", command=merge).grid()
    tkinter.Button(app, text="verschlüsseln", command=encrypt_pdf).grid()
    tkinter.Button(app, text="beenden", command=beenden).grid()
    box=tkinter.Listbox(app, selectmode='browse')
    box.place(width=400, height=80, y=100)
    workflow = tkinter.IntVar()
    workflow.set(0)
    tkinter.Checkbutton(app, variable=workflow, onvalue=1, offvalue=0).place(x=0, y=200)
    workflow.set(1)
    ein=tkinter.Entry(app)
    ein.place(x=20, y=200)
    app.mainloop()


def pic():
    applic = tkinter.Toplevel(root)
    applic.title("File converter")
    bilder = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Pictures')
    bilder = os.path.join(bilder, "converted_files")

    listboxfile = tkinter.Listbox(applic, selectmode='browse')
    listboxfile.place(x=100, y=250, width=250, height=100)
    types = r" *.png  *.tiff  *.gif  *.jpg  *.ico"

    def new_img():
        input = tkinter.filedialog.askopenfilenames(parent=applic, title="Dateien auswählen", filetypes=[("Bilder:", types)])
        listboxfile.delete('0', 'end')
        for file in applic.tk.splitlist(input):
            listboxfile.insert('end', file)
        return input

    def add_img():
        input = tkinter.filedialog.askopenfilenames(parent=applic, title="Dateien auswählen", filetypes=[("Bilder:", types)])
        for file in applic.tk.splitlist(input):
            listboxfile.insert('end', file)

    applic.geometry("350x350")
    options=['.png', '.tiff', '.pdf', '.gif', '.TIF', '.ico', '.jpg']
    variable = tkinter.StringVar(applic)
    variable.set(options[0])
    opt = tkinter.OptionMenu(applic, variable, *options)
    opt.config(width=90, font=('Helvetica', 12))
    opt.pack()

    def conv():
        messagebox.showwarning(title='Wichtig!', message='Dateien gleicher Endung werden überschrieben!!')
        input = listboxfile.get('0', 'end')
        i=0
        puffer = os.path.dirname(os.path.abspath(sys.argv[0]))
        for file in applic.tk.splitlist(input):
            try:
                os.remove(os.path.join(puffer, "conv.gif"))
            except:
                pass
            f=bilder
            _, e = os.path.splitext(file)
            i+=1
            im = Image.open(file)
            output = os.path.join(f, "_", str(i), variable.get())

            if e == '.tiff' or e == '.png' or e == '.TIF':
                im.save(os.path.join(puffer, 'conv.gif'))
                im = Image.open(os.path.join(puffer, 'conv.gif'))
            if im.mode != 'RGB' and variable.get() == '.jpg':
                im = im.convert('RGB')
            if variable.get() == '.jpg':
                im.save(output, "JPEG")

            else:
                pass
            im.save(output)

        if check == 1:
            listboxfile.delete('0', 'end')

        else:
            pass

        messagebox.showinfo(title="Konvertierung erfolgreich", message="Konvertierung erfolgreich!")
    but=tkinter.Button(applic, text="select new files", command=new_img)
    but.place(y=300)
    but.pack()
    tkinter.Button(applic, text="select more files", command=add_img).pack()
    tkinter.Button(applic, text="convert", command=conv).pack()
    check = tkinter.IntVar()
    tkinter.Checkbutton(applic, text="Dateiliste danach verwerfen", variable=check, onvalue=1, offvalue=0).place(y=210, x=100)
    check.set(1)

    def beende():
        applic.destroy()
    tkinter.Button(applic, text="beenden", command=beende).pack()
    applic.mainloop()


def main():
    desktop = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Desktop')
    bilder = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Pictures')

    def create_folder():

        os.makedirs(os.path.join(bilder, "converted_files"))

    def create_shortcut():
        datei = os.path.abspath(sys.argv[0])

        s = CreateObject(ShellLink)
        s.SetPath(datei)

        p = s.QueryInterface(IPersistFile)
        p.Save(os.path.join(desktop, "File editor.lnk"), True)

        s = CreateObject(ShellLink)
        p = s.QueryInterface(IPersistFile)
        p.Load(os.path.join(desktop, "File editor.lnk"), True)

    def pdf():
        pdf_1()
        
    def cov():
        pic()

    var1=os.path.isdir(os.path.join(bilder, "converted_files"))

    if var1 is not True:
        create_folder()

    root.title("File editor")
    tkinter.Label(root, text="Was möchtest du machen?").pack()
    tkinter.Button(root, text="Pdf editor", command=pdf).pack()
    tkinter.Button(root, text="Picture convert", command=cov).pack()
    tkinter.Button(root, text="Create shortcut", command=create_shortcut).pack()
    root.mainloop()

if __name__ == '__main__':
    main()
So in Bezug auf os.path.join besser? Ich habe auch nocheinmal nach großgeschriebenen variablen ausschau gehalten, aber keine gefunden. Um die Funktionen in Funktionen habe ich mich nicht gekümmert, bzw. wusste nicht wie ich das machen sollte.

Mfg
Christian

Re: File editor

Verfasst: Samstag 27. Februar 2021, 20:10
von Fire Spike
Verschiebe einfach die Funktionen auf die oberste Ebene. Das ist alles.

Re: File editor

Verfasst: Sonntag 28. Februar 2021, 10:12
von rennmaus
@Fire Spike Ich habe das jetzt alles schon in Klassen umgeschrieben, aber trotzdem danke!