mein Name ist Mischel und ich arbeite gerade zum ersten mal mit Python.
Gleich vorweg, ich nutze Chat GPT 4 und kam bisher sehr weit. Ich besitze keine fundamentalen Kenntnisse in Python, da ich Motion Designer bin.
Ich möchte aber in Zukunft mehr darüber lernen und probiere gerade eine .EXE zu schreiben.
Folgendes ist mein Ziel, ich habe eine sogenannte "Insertliste" in der 3 Spalte vorhanden sind.
Die erste Spalte ist ein Timecode.
Die zweite Spalte ein Hinweis wie "BB" oder "BB rechts" oder "BB links" oder auch anderes wie Karte, Grafik, Abspann, Infopanel, Insert, UT, Quelle. Das sind die gängigsten Infos.
Manchmal steht aber dort auch noch Zusatz Hinweis, die nicht mit in meine .TXT übernommen werden sollen.
Mein Ziel ist es alle Infos aus der .DOCX die relevant für mich sind, also BB, Inserts und Infopanel auszugeben und so zu formatieren Bspw:
BB,Dr. Andrew Birley,Leiter Ausgrabungsstätte Vindolanda
Infopanel,*BrigantenBriganten*,loser Zusammenschluss keltischer Volksgruppen in Nordost-Britannien
Insert, 1955
Was hier mit Sternchen markiert ist, wird fett geschriebene später in After Effects.
Mein Ziel ist es diesen Vorgang zu automatisieren. Ich möchte die TXT mit Java script laden und mir automatisch Bauchbinden, Inserts und Infopanles erstellen lassen, anhand von dafür vorgesehene Vorlage in einem After Effects Projekt.
Das klappt auch alles soweit, wenn in der .DOCX nur BB steht, aber sobald dort mehr als BB steht Bspw. "BB rechts" oder "BB links" wird es zwar gezählt, aber nicht in meiner TXT ausgegeben.
Was kann ich tun? Das wäre für die Funktion des Skriptes essenziel. Vielleicht kann mir jemand helfen, der mehr Ahnung hat?
Über eine Hilfe wäre ich sehr dankbar
![Smile :-)](./images/smilies/icon_smile.gif)
Code: Alles auswählen
[b]
Das ist mein bisheriger code:[/b]
import os
import tkinter as tk
from tkinter import ttk, filedialog, messagebox, scrolledtext
from docx import Document
results = {}
def extract_info_from_docx(docx_file, progress_var, seen_entries, counts):
doc = Document(docx_file)
table = doc.tables[0]
print(results)
total_rows = len(table.rows)
for i, row in enumerate(table.rows):
cell_content = row.cells[0].text.strip()
name = row.cells[1].text.strip()
subtitle = row.cells[2].text.strip()
try:
parts = [] # parts should be reset for every row.
if len(row.cells) > 2:
cell_content = row.cells[1].text.strip()
print(f"Processing cell_content: '{cell_content}'")
if "BB" in cell_content and cell_content != "":
counts["BB"] += 1
print(f"Updated count for BB: {counts['BB']}") # Dieser Befehl gibt jedes Mal eine Nachricht aus, wenn "BB" gefunden und gezählt wird
elif cell_content in ["Infopanel", "Insert"]:
counts[cell_content] += 1
# ... (anderer Code in der Funktion bleibt unverändert)
for paragraph in row.cells[2].paragraphs:
formatted_text = ""
for run in paragraph.runs:
if run.bold:
formatted_text += run.text + " "
update_output_with_tags(cell_content, run.text, "")
elif run.italic:
formatted_text += run.text + " "
update_output_with_tags(cell_content, "", run.text)
else:
formatted_text += run.text + " "
update_output_with_tags(cell_content, "", "")
parts.append(formatted_text.strip())
name = parts[0] if parts else ""
subtitle = ' '.join(parts[1:]) if len(parts) > 1 else ""
unique_id = f"{name}_{subtitle}"
if unique_id not in seen_entries:
results[i] = {'marker': cell_content, 'name': name, 'subtitle': subtitle}
seen_entries.add(unique_id)
progress_percentage = (i + 1) / total_rows * 50
progress_var.set(progress_percentage)
progress_label["text"] = f"{int(progress_percentage)}%"
update_output_with_tags(cell_content, name, subtitle)
real_time_output.yview(tk.END) # Scroll zum letzten Eintrag
app.update()
else:
print(f"Skipping row {i} due to insufficient cells. Cells found: {len(row.cells)}, Content: {[cell.text for cell in row.cells]}")
except Exception as e:
print(f"Error processing row {i}: {e}")
return results, counts
def save_to_txt(file_path, info):
try:
with open(file_path, 'w', encoding='utf-8') as f:
for line in info.values():
f.write(f"{line['marker']},{line['name']},{line['subtitle']}\n")
except Exception as e:
messagebox.showerror("Error", f"Error saving to TXT file: {str(e)}")
def select_docx():
try:
file_paths = filedialog.askopenfilenames(filetypes=[("DOCX files", "*.docx")])
if file_paths:
docx_var.set(";".join(file_paths))
base_name = os.path.splitext(os.path.basename(file_paths[0]))[0]
txt_var.set(os.path.join(os.path.dirname(file_paths[0]), base_name + ".txt"))
except Exception as e:
messagebox.showerror("Error", f"Error reading DOCX file: {str(e)}")
def select_txt():
file_path = filedialog.asksaveasfilename(filetypes=[("TXT files", "*.txt")], defaultextension=".txt")
if file_path:
txt_var.set(file_path)
def convert():
seen_entries = set()
docx_paths = docx_var.get().split(";")
counts = {"BB": 0, "Infopanel": 0, "Insert": 0}
if not docx_paths:
messagebox.showerror("Error", "Please select DOCX paths!")
return
try:
progress_var.set(0)
progress_label["text"] = "0%"
total_docs = len(docx_paths)
for idx, docx_path in enumerate(docx_paths):
txt_path = os.path.splitext(docx_path)[0] + ".txt"
info, counters = extract_info_from_docx(docx_path, progress_var, seen_entries, counts)
bb_label["text"] = f"BB: {counters['BB']}"
infopanel_label["text"] = f"Infopanel: {counters['Infopanel']}"
insert_label["text"] = f"Insert: {counters['Insert']}"
info = {k: v for k, v in info.items() if v['marker'] in ['Insert', 'BB', 'Infopanel']}
print(info)
save_to_txt(txt_path, info)
progress_var.set(int((idx + 1) / total_docs * 100))
progress_label["text"] = f"{int(progress_var.get())}%"
app.update()
messagebox.showinfo("Success", "Conversion completed successfully!")
except Exception as e:
messagebox.showerror("Error", f"An error occurred: {str(e)}")
app = tk.Tk()
app.title("DOCX to TXT Converter for Kelvinfilm")
# Zeilen und Spalten für das Hauptfenster `app` anpassen
app.grid_rowconfigure(0, weight=1)
app.grid_columnconfigure(0, weight=1)
style = ttk.Style()
style.configure("TButton", background="#448ce6")
style.configure("TProgressbar", troughcolor='white', background='#448ce6')
docx_var = tk.StringVar()
txt_var = tk.StringVar()
progress_var = tk.IntVar()
frame = ttk.Frame(app, padding="10")
frame.grid(sticky=(tk.W, tk.E, tk.N, tk.S))
# Label und Progressbar Initialisierung
progress_label = ttk.Label(frame, text="0%")
# Definiere bb_label, infopanel_label und insert_label hier vorab
bb_label = ttk.Label(frame, text="BB: 0")
infopanel_label = ttk.Label(frame, text="Infopanel: 0")
insert_label = ttk.Label(frame, text="Insert: 0")
# Zeilen und Spalten für das `frame` anpassen
progress_label = ttk.Label(frame, text="0%")
progress_label.grid(row=3, column=0, columnspan=3, pady=5)
ttk.Button(frame, text="Convert", command=convert).grid(row=4, column=0, columnspan=3, pady=10)
frame.grid_rowconfigure(0, weight=1)
frame.grid_rowconfigure(1, weight=1)
frame.grid_rowconfigure(2, weight=1)
frame.grid_rowconfigure(3, weight=1)
frame.grid_rowconfigure(4, weight=1) # Für die Convert-Taste
frame.grid_rowconfigure(5, weight=1) # Für das Logo
frame.grid_columnconfigure(1, weight=1)
# Alle Widgets werden unverändert hinzugefügt. Ich habe die `sticky`-Attribute nur dort gesetzt, wo es nötig war.
ttk.Label(frame, text="Open DOCX:").grid(row=0, column=0, pady=5, sticky=tk.W)
ttk.Label(frame, text="Save TXT:").grid(row=1, column=0, pady=5, sticky=tk.W)
ttk.Entry(frame, textvariable=docx_var, width=40).grid(row=0, column=1, pady=5, sticky=(tk.W, tk.E))
ttk.Button(frame, text="Browse", command=select_docx).grid(row=0, column=2, pady=5, padx=5)
ttk.Entry(frame, textvariable=txt_var, width=40).grid(row=1, column=1, pady=5, sticky=(tk.W, tk.E))
ttk.Button(frame, text="Browse", command=select_txt).grid(row=1, column=2, pady=5, padx=5)
progress_bar = ttk.Progressbar(frame, orient="horizontal", mode="determinate", variable=progress_var)
progress_bar.grid(row=2, column=0, columnspan=3, pady=10, padx=5, sticky=(tk.W, tk.E))
progress_label.grid(row=3, column=0, columnspan=3, pady=5)
ttk.Button(frame, text="Convert", command=convert).grid(row=4, column=0, columnspan=3, pady=10)
# Logo-Teil
try:
logo_path = r"\\nexis\Grafik_TEMP\_Kelvinfilm-Druck\_LOGO_KELVINFILM\Export\Logo_Kelvinfilm_CMYK_blau.png"
logo_image = tk.PhotoImage(file=logo_path)
logo_image = logo_image.subsample(7)
ttk.Label(frame, image=logo_image).grid(row=5, column=0, columnspan=3, pady=5)
except Exception as e:
print(f"Error loading logo: {e}")
ttk.Label(frame, text="Kelvinfilm").grid(row=5, column=0, columnspan=3, pady=5)
# Hinzufügen des scrolledtext-Widgets zur GUI, direkt zwischen dem Convert-Button und dem Fortschrittslabel
real_time_output = scrolledtext.ScrolledText(frame, wrap=tk.WORD, width=50, height=10)
real_time_output.grid(row=5, column=0, columnspan=3, pady=10, padx=5, sticky=(tk.W, tk.E))
# Formatierungstags definieren
real_time_output.tag_configure("bold", font=("Arial", 10, "bold"))
real_time_output.tag_configure("italic", font=("Arial", 10, "italic"))
real_time_output.tag_configure("normal", font=("Arial", 10)) # für dünnen Text
real_time_output.tag_configure("other", foreground="dark green", font=("Arial", 10, "bold"))
real_time_output.tag_configure("BB", foreground="blue", font=("Arial", 10, "bold"))
real_time_output.tag_configure("Insert", foreground="green", font=("Arial", 10, "bold"))
real_time_output.tag_configure("Infopanel", foreground="purple", font=("Arial", 10, "bold"))
def update_output_with_tags(marker, name, subtitle):
formatted_name = name
formatted_subtitle = subtitle
# Standardtext
real_time_output.insert(tk.END, f"Verarbeite: ", "bold")
# Text mit spezifischem Tag je nach Markierungstyp
if marker in ["BB", "Insert", "Infopanel"]:
real_time_output.insert(tk.END, f"{marker} ", marker)
else:
real_time_output.insert(tk.END, f"{marker} ", "other")
# Formatierter Name und Untertitel
for part, tag in [(name, "bold"), (subtitle, "italic")]:
real_time_output.insert(tk.END, f"{part} ", tag)
real_time_output.insert(tk.END, "\n")
real_time_output.yview(tk.END) # Scroll zum letzten Eintrag
# Setze das Grid für die vorher definierten Labels
bb_label.grid(row=6, column=0, pady=5)
infopanel_label.grid(row=6, column=1, pady=5)
insert_label.grid(row=6, column=2, pady=5)
# Die von Ihnen bereitgestellte Funktion, um den Code in einem neuen Fenster anzuzeigen
def display_code_in_window():
code_window = tk.Toplevel(app)
code_window.title("Code Viewer")
# Hinzufügen eines Scrollbaren Textfeldes
text_widget = scrolledtext.ScrolledText(code_window, wrap=tk.WORD, width=80, height=40)
text_widget.pack(padx=10, pady=10, fill=tk.BOTH, expand=True)
# Den gesamten Code im Textfeld anzeigen
with open(__file__, "r", encoding="utf-8") as file:
code_content = file.read()
text_widget.insert(tk.END, code_content)
text_widget.config(state=tk.DISABLED) # Schreibschutz aktivieren, damit der Benutzer den Code nicht bearbeiten kann
def display_log_in_window():
log_window = tk.Toplevel(app)
log_window.title("Log Viewer")
# Hinzufügen eines Scrollbaren Textfeldes
text_widget = scrolledtext.ScrolledText(log_window, wrap=tk.WORD, width=80, height=40)
text_widget.pack(padx=10, pady=10, fill=tk.BOTH, expand=True)
# Für diesen Beispielcode gehe ich davon aus, dass Sie die Terminalausgabe in eine Datei mit dem Namen "log.txt" im aktuellen Verzeichnis umleiten.
# Wenn Sie den Pfad oder den Dateinamen ändern möchten, aktualisieren Sie einfach den folgenden Pfad.
log_file_path = "log.txt"
if os.path.exists(log_file_path):
with open(log_file_path, "r", encoding="utf-8") as file:
log_content = file.read()
text_widget.insert(tk.END, log_content)
text_widget.config(state=tk.DISABLED) # Schreibschutz aktivieren, damit der Benutzer den Inhalt nicht bearbeiten kann
else:
text_widget.insert(tk.END, "No log file found!")
text_widget.config(state=tk.DISABLED)
ttk.Button(frame, text="Show Log file", command=display_log_in_window).grid(row=7, column=0, columnspan=3, pady=10)
app.mainloop()