Теперь, когда мое приложение почти закончено и у меня была возможность протестировать его под OS X, я обнаружил ошибку, связанную с отображением страниц. Мое приложение имеет несколько страниц, из которых пользователь может выбирать. Страницы реализованы в виде фреймов с соответствующим содержимым, размещенным сверху. Для переключения между страницами я написал виджет под названием «pageSwitcher». Этот виджет сохраняет текущий объект страницы в переменной класса (
Код: Выделить всё
self.currentlyDisplayedPageПроблема описана здесь
Под Linux (Ubuntu 24.04.3 LTS) это работает отлично. Но под OSX (10.13.6) поведение другое. Когда я впервые переключаюсь на страницу, она отображается правильно. Но если я попытаюсь переключиться на страницу, которая отображалась ранее в текущей среде выполнения, она просто не будет отображаться, пока я не выполню одно из следующих действий:
Если я щелкну за пределами приложения (например, рабочего стола), страница будет отображаться правильно. Кроме того, если я наведу указатель мыши на элементы, имеющие привязки событий или , страница отобразится, как только я наведу на них указатель мыши. Кроме того, работают интерактивные элементы, такие как записи и кнопки; как только я нажимаю на запись или кнопку, страница отображается, а в случае кнопки выполняются соответствующие функции. Насколько я вижу, новая страница установлена, и все виджеты присутствуют, но они не отображаются, пока я не выполню одну из операций, подробно описанных выше.
Я пытался это исправить:
Используя .update_idletasks(), чтобы принудительно отобразить страницу. Это сделало его иногда лучше, иногда хуже (страница будет отображаться, но в худшем случае это может занять несколько минут). Поэтому я решил, что это не решение. Я также пытался использовать другую версию Python (с 3.12.12 по 3.14.2), надеясь, что это ошибка в конкретной версии (чего, похоже, не было). Я тестировал это под OSX Sequoia (15.7.3) и (к сожалению) получил те же результаты, поэтому предполагаю, что это не ошибка в конкретной версии OSX.
Я не знаю, почему это происходит и как это исправить. Вот минимальный пример, который выдает ошибку при использовании пустых (цветных) фреймов в качестве страниц:
Код: Выделить всё
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()
Я создаю автономное приложение ondir с помощью pyinstaller. Но ошибка возникает при непосредственном запуске кода и при запуске сборки приложения с помощью pyinstaller.
Если кто-то знает решение, которое не требует, чтобы я сам исправлял Tcl/Tk (я где-то читал, что Tcl/Tk содержит ошибки под OSX) или переписывал все мое приложение в другой среде графического интерфейса, которая «я знаю, работает под OSX», дайте мне знать.
Подробнее здесь: https://stackoverflow.com/questions/798 ... nder-macos
Мобильная версия