Seite 1 von 1

Klassen Vererbung Problem

Verfasst: Montag 22. Februar 2021, 12:21
von rennmaus
Hi!
Ich glaube, dass ich einfach vergessen habe, wie Vererbung funktioniert, Ich möchte nämlich root an pdf vererben, um ein TopLevel zu erzeugen. Hier mal mein Code (Ich Copy Paste den gerade aus einer anderen Datei von mir, also sind da wahrscheinlich viele Fehler drin, die einfach erstmal nicht beachten, geht mir nur im die __init__ in Pdf_edit())

Code: Alles auswählen

import os, tkinter, sys, webbrowser, math, requests, tkinter.simpledialog, os.path
from PyPDF2 import PdfFileReader, PdfFileWriter
from tkinter import filedialog, messagebox
from PIL import Image
from comtypes.client import CreateObject
from comtypes.persist import IPersistFile
from comtypes.shelllink import ShellLink
from glob import glob
from random import randint
from pikepdf import Pdf, Encryption


class MainWindow:
    def __init__(self):
        self.desktop = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Desktop')
        self.bilder = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Pictures')
        self.root = tkinter.Tk()

    def main(self):
        var1 = os.path.isdir(self.bilder + "\\converted_files")

        if var1 is not True:
            create_folder()

        self.root.title("File editor 2.2.0")
        self.root.geometry("400x175")
        tkinter.Label(self.root, text="Was möchtest du machen?").pack()
        tkinter.Button(self.root, text="Pdf editor", command=pdf).pack()
        tkinter.Button(self.root, text="Picture convert", command=cov).pack()
        tkinter.Button(self.root, text="Compress Picture", command=comp).pack()
        tkinter.Button(self.root, text="Neue Version suchen", command=new_v).pack()
        tkinter.Button(self.root, text="Create shortcut", command=create_shortcut).pack()



    def create_folder(self):

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

    def create_shortcut(self):
        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 new_v(self):
        try:
            webbrowser.open_new_tab('https://mega.nz/folder/0PQUWJBY#5uzbZalOMbdzTT4RqfW1ig')
        except:
            res = messagebox.askquestion(title="Inkompabilität", message="Ihr Browser wird wahrscheinlich nicht"
                                                            " unterstützt. Wenn sie auf Ja drücken, "
                                                            "wird folgender Link kopiert:"
                                                            "\nhttps://mega.nz/folder/0PQUWJBY#5uzbZalOMbdzTT4RqfW1ig")
            if res == 'yes':
                try:
                    root.clipboard_clear()
                finally:
                    root.clipboard_append("https://mega.nz/folder/0PQUWJBY#5uzbZalOMbdzTT4RqfW1ig")


class Pdf_edit(MainWindow):
    def __init__(self):
        self.pdf_writer = PdfFileWriter()
        self.app = tkinter.Toplevel(root)
        self.app.title("Pdf editor")
        self.app.geometry("400x220")
        self.box = tkinter.Listbox(self.app, selectmode='browse')
        self.workflow = tkinter.IntVar()
        self.ein = tkinter.Entry(self.app)

    def main(self):
        tkinter.Button(self.app, text="add files", command=self.add_files).grid(column=0, row=2)
        tkinter.Button(self.app, text="verbinden", command=self.merge).grid(column=5, row=2)
        tkinter.Button(self.app, text="verschlüsseln", command=self.encrypt_pdf).grid(column=10, row=2)
        tkinter.Button(self.app, text="aufteilen", command=self.split_pdf).grid(column=15, row=2)
        tkinter.Button(self.app, text="html_pdf", command=self.html_to_pdf).grid(column=20, row=2)
        tkinter.Button(self.app, text="beenden", command=self.beenden).grid(column=25, row=2)
        self.box.place(width=400, height=120, y=70)
        self.workflow.set(0)
        tkinter.Checkbutton(self.app, variable=self.workflow, onvalue=1, offvalue=0).place(x=0, y=200)
        self.workflow.set(0)
        self.ein.place(x=20, y=200)
        self.app.mainloop()

    def split_pdf(self):
        bilder = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Pictures')
        bilder += "/converted_files/"
        num = 0
        files = self.box.get('0', 'end')
        for file in self.app.tk.splitlist(files):
            pdf_reader = PdfFileReader(file)
            for page in range(pdf_reader.getNumPages()):
                num += 1
                pdf_writerr = PdfFileWriter()
                pdf_writerr.addPage(pdf_reader.getPage(page))
                with open(bilder + "splited_page_" + str(num) + ".pdf", 'wb') as out:
                    pdf_writerr.write(out)
        messagebox.showinfo("Erfolgreich", "Das aufteilen der Seiten war erfolgreich!")

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

    def merge(self, name='mergedPDF'):
        work = self.workflow.get()
        if work == 0:
            files = self.box.get('0', 'end')
            for file in self.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 = self.box.get('0', 'end')
            files = self.app.tk.splitlist(files)
            e = self.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(self):

        names = self.box.get('0', 'end')
        password = tkinter.simpledialog.askstring("Passwort", "Passwort:")
        for file in app.tk.splitlist(names):
            pdf = Pdf.open(file)
            bilder = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Pictures')
            bilder += "/converted_files/"
            pdf.save(bilder + file.split("/")[-1] + "-verschlüsselt.pdf",
                     encryption=Encryption(owner=password, user=password, R=4))
            pdf.close()
        messagebox.showinfo(title="Erfolgreich", message="Die verschlüsselung war erfolgreich!")

    def html_to_pdf(self):
        files = box.get('0', 'end')
        for file in app.tk.splitlist(files):
            code = open(file).read()
            apiKey = 'hier_gibt_es_nichts_zu_sehen ;)'
            url = 'https://api.sejda.com/v2/html-pdf'
            r = requests.post(url, json={
                'viewportWidth': 1200,
                "htmlCode": code
            }, headers={
                'Authorization': 'Token: {}'.format(apiKey)
            })
            bilder = os.path.join(os.path.join(os.environ['USERPROFILE']), 'Pictures')
            bilder += "/converted_files/"
            open(bilder + 'html.pdf', 'wb').write(r.content)

    def beenden(self):
        app.destroy()


pdf = Pdf_edit()
pdf.main()
Wenn ich den Code so ausführe, bekomme ich immer diesen Error:

Code: Alles auswählen

Traceback (most recent call last):
  File "D:/python/anwendungen/File_editor V2_classes.py", line 180, in <module>
    pdf = Pdf_edit()
  File "D:/python/anwendungen/File_editor V2_classes.py", line 72, in __init__
    self.app = tkinter.Toplevel(root)
NameError: name 'root' is not defined
Freue mich über Hilfe!

Mfg
Christian

Re: Klassen Vererbung Problem

Verfasst: Montag 22. Februar 2021, 12:55
von rennmaus
Wenn ich es so mache:

Code: Alles auswählen

mw = MainWindow()
        self.app = tkinter.Toplevel(mw.root)
wird ein tkinter Window erstellt, was ich nicht möchte, denn es gibt dann ja schon eins

Re: Klassen Vererbung Problem

Verfasst: Montag 22. Februar 2021, 13:39
von Sirius3
`os.path` importiert man nicht explizit, weil es schon mit `os` mitimportiert wird. Aber man benutzt auch os.path eigentlich nicht mehr, sondern pathlib, und da ist mit pathlib.Path.home() schon eine Methode dabei, um das Userverzeichnis Systemunabhängig zu bekommen. Pfade setzt man nicht mit + zusammen.
`var1` ist ein ganz schlechter Variablenname, weil der absolut nichtsagend ist. Zudem auch gar nicht nötig, weil isdir auch im if stehen könnte.
Bei `create_folder` fehlt ein self. Da gibt es also nicht nur Lücken in der Vererbung.
Auch sehe ich nicht wirlich, warum Du hier vererbst. Wenn Pdf_edit ein TopLevel erzeugt, Mainwindow aber eine Tk-Instanz, dann gibt es da nichts zu vererben.

Re: Klassen Vererbung Problem

Verfasst: Montag 22. Februar 2021, 13:45
von rennmaus
Soll ich dann ein neues tkinter.Tk() machen?

Re: Klassen Vererbung Problem

Verfasst: Montag 22. Februar 2021, 13:48
von peterpy
Hallo rennmaus,

Du hast vergessen wie Vererbung geht?
Klasse B erbt von Klasse A

Code: Alles auswählen

class B(A):
    def __init__(self):
        A.__init(self)
Oder zu deiner Frage, wie ein Fenster versteckt wird:

Code: Alles auswählen

import tkinter as tk
def main():
    root = tk.Tk()
    fenster = tk.Label(root, text='blablabla',
                       font=('helvetica', '60')).pack()    
    verstecke_fenster(root)
    root.mainloop()

def verstecke_fenster(root):
    root.withdraw()
    root.after(9999, zeig_das_fenster(root))

def zeig_das_fenster(root):
    root.deiconify()

if __name__ == '__main__':
    main()
Aber wieso rufst Du nicht zuerst das Mainwindow auf und übergibst root mit dem Aufruf an Pdf_edit?
Gruss Peter

Re: Klassen Vererbung Problem

Verfasst: Montag 22. Februar 2021, 13:59
von Sirius3
@rennmaus: nein, Du sollst schon ein TopLevel machen, wenn Du ein zweites Fenster brauchst, aber Mainwindow und Pdf_edit haben halt nichts miteinander zu tun, und daher macht Vererbung da keinen Sinn.

Re: Klassen Vererbung Problem

Verfasst: Montag 22. Februar 2021, 14:48
von rennmaus
Danke für eure Hilfe! Jetzt habe ich es geschafft!

Mfg
Christian