Da meine Anwendung nun fast fertig ist und ich Gelegenheit hatte, sie unter OS X zu testen, habe ich einen Fehler bei der Anzeige von Seiten gefunden. Meine Anwendung verfügt über mehrere Seiten, aus denen der Benutzer auswählen kann. Die Seiten sind als Frames implementiert und die entsprechenden Inhalte werden darüber platziert. Zum Wechseln zwischen Seiten habe ich ein Widget namens „pageSwitcher“ geschrieben. Dieses Widget speichert das aktuelle Seitenobjekt in einer Klassenvariablen (
Code: Select all
self.currentlyDisplayedPageHier angegebenes Problem
Unter Linux (Ubuntu 24.04.3 LTS) funktioniert dies einwandfrei. Aber unter OSX (10.13.6) erhalte ich ein anderes Verhalten. Wenn ich zum ersten Mal zu einer Seite wechsle, wird sie korrekt angezeigt. Wenn ich jedoch versuche, zu einer Seite zu wechseln, die zuvor in der aktuellen Laufzeit angezeigt wurde, wird sie einfach erst angezeigt, wenn ich einen der folgenden Schritte ausführe:
Wenn ich außerhalb der Anwendung (z. B. Desktop) klicke, wird die Seite korrekt angezeigt. Wenn ich außerdem die Maus über Elemente bewege, die über die Ereignisbindungen oder verfügen, wird die Seite angezeigt, sobald ich die Maus darüber bewege. Darüber hinaus funktionieren interaktive Elemente wie Einträge und Schaltflächen; Sobald ich in einen Eintrag oder auf einen Button klicke, wird die Seite angezeigt und im Falle eines Buttons wird die entsprechende Funktionalität ausgeführt. So wie ich es sehe, ist die neue Seite eingerichtet und alle Widgets sind vorhanden, aber sie werden erst angezeigt, wenn ich einen der oben beschriebenen Vorgänge ausführe.
Ich habe versucht, das Problem zu beheben, indem ich:
.update_idletasks() verwendet habe, um die Anzeige der Seite zu erzwingen. Dadurch wurde es manchmal besser, manchmal schlechter (die Seite wird angezeigt, aber im schlimmsten Fall kann es Minuten dauern). Deshalb habe ich beschlossen, dass dies keine Lösung ist. Ich habe auch versucht, eine andere Python-Version (von 3.12.12 bis 3.14.2) zu verwenden, in der Hoffnung, dass dies ein Fehler in einer bestimmten Version war (was anscheinend nicht der Fall war). Ich habe dies unter OSX Sequoia (15.7.3) mit (leider) genau den gleichen Ergebnissen getestet, daher gehe ich davon aus, dass es sich nicht um einen Fehler in einer bestimmten OSX-Version handelt.
Ich weiß nicht, warum das passiert und wie ich es beheben kann. Hier ist ein Minimalbeispiel, das den Fehler erzeugt, wenn leere (farbige) Rahmen als Seiten verwendet werden:
Code: Select all
import tkinter as tk
class PageSwitcher(tk.Frame):
def __init__(self, parent:tk, desiredHeight:int, desiredWidth:int) -> None:
self.managedPages:list[tk.Frame] = []
self.currentlyDisplayedPage:tk.Frame = None
tk.Frame.__init__(self, parent, height=desiredHeight, width=desiredWidth)
self.grid_propagate(False)
self.rowconfigure(index=(0,2), weight=1)
self.columnconfigure(index=(0,2), weight=1)
def addPage(self, pageToAdd:tk.Frame) -> None:
self.managedPages.append(pageToAdd)
def displayPage(self, pageId:int) -> None:
if self.currentlyDisplayedPage != None:
self.currentlyDisplayedPage.grid_remove()
self.currentlyDisplayedPage = self.managedPages[pageId]
self.currentlyDisplayedPage.grid(row=1, column=1)
class PageSelector(tk.Frame):
def __init__(self, parent:tk, desiredHeight:int, desiredWidth:int, pageSwitchFunction) -> None:
self.pageSwitchFunction = pageSwitchFunction
self.width = desiredWidth
self.managedSelectors:list[PageSelector.Selector] = []
tk.Frame.__init__(self, parent, height=desiredHeight, width=desiredWidth)
self.grid_propagate(False)
def registerPage(self, pageName:str, pageId:int):
selector = self.Selector(
parent=self,
desiredWidth=self.width-10, #For 5px of padding on each side of selector
name=pageName,
pageId=pageId,
selectFunction=self.select
)
selector.grid(row=self.grid_size()[1], column=0, padx=5, pady=2)
self.managedSelectors.append(selector)
def select(self, pageId) -> None:
self.pageSwitchFunction(pageId)
class Selector(tk.Frame):
def __init__(self, parent:tk, name:str, pageId:int, selectFunction, desiredWidth:int) -> None:
self.pageId = pageId
self.selectFunction = selectFunction
tk.Frame.__init__(self, parent, height=32, width=desiredWidth, border=2, relief="raised")
self.grid_propagate(False)
self.name = tk.Label(self, text=name, font="Bold")
self.name.grid(row=1, column=0, padx=5)
self.bind("", self.select)
self.name.bind("", self.select)
def select(self, event:tk.Event) -> None:
self.selectFunction(self.pageId)
def main():
height = 600
width = 600
window = tk.Tk()
window.geometry(f"{width}x{height}")
pageSwitcher = PageSwitcher(window, height, width//2)
pageSelector = PageSelector(window, height, width//2, pageSwitcher.displayPage)
pageSwitcher.grid(row=0, column=1)
pageSelector.grid(row=0, column=0)
pageNamesAndColors = ["red", "orange", "yellow", "green", "lime", "lightBlue", "blue", "purple", "pink"]
for index, color in enumerate(pageNamesAndColors):
newPage = tk.Frame(pageSwitcher, height=height, width=width//2, bg=color)
pageSwitcher.addPage(newPage)
pageSelector.registerPage(pageName=f"{color} Page", pageId=index)
window.mainloop()
main()
Ich erstelle eine eigenständige Ondir-Anwendung mit Pyinstaller. Der Fehler tritt jedoch auf, wenn der Code direkt ausgeführt wird und wenn der App-Build mit pyinstaller ausgeführt wird.
Wenn jemand eine Lösung kennt, bei der ich Tcl/Tk nicht selbst reparieren muss (ich habe irgendwo gelesen, dass Tcl/Tk unter OSX fehlerhaft ist) oder meine gesamte App in einem anderen GUI-Framework neu schreiben muss, von dem ich weiß, dass es unter OSX funktioniert, lassen Sie es mich bitte wissen.
Mobile version