Klassen Vererbung Problem

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
rennmaus
User
Beiträge: 217
Registriert: Dienstag 4. August 2020, 10:24

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
rennmaus
User
Beiträge: 217
Registriert: Dienstag 4. August 2020, 10:24

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
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

`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.
rennmaus
User
Beiträge: 217
Registriert: Dienstag 4. August 2020, 10:24

Soll ich dann ein neues tkinter.Tk() machen?
Benutzeravatar
peterpy
User
Beiträge: 188
Registriert: Donnerstag 7. März 2013, 11:35

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
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

@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.
rennmaus
User
Beiträge: 217
Registriert: Dienstag 4. August 2020, 10:24

Danke für eure Hilfe! Jetzt habe ich es geschafft!

Mfg
Christian
Antworten