использование классов виджетов Python - PullRequest
1 голос
/ 18 января 2012

Если это не самоочевидно, я пишу на Python 2.7 tkinter около четырех месяцев. Я понимаю, что

from Tkinter import* #access to libraries and widgets to write python code 
root=Tk() #creates CLI window that actually runs the module
root.mainloop() #repeats the module code ad nauseum
class = Class(root) #no clue what this actually does

Я написал несколько простых модулей для одного класса, т.е.

from Tkinter import*  
class Code:     
    def __init__(self, parent):
    self.myParent = parent      
    self.main_frame = Frame(parent, background="light blue")     
    self.main_frame.pack(expand=YES, fill=BOTH)  
    self.enter = Entry(self.main_frame, width=30)     
    self.enter.pack(side=LEFT, expand=NO)
root = Tk() 
code = Code(root) 
root.mainloop()

Теперь я наткнулся на забавный маленький класс виджетов в Интернете - который я разобрал до самого необходимого - что может сделать это скучное окно ввода окном автозаполнения, т.е.

import Tkinter

class AutocompleteEntry(Tkinter.Entry):

def set_completion_list(self, completion_list):
    self._completion_list = completion_list
    self._hits = []
    self._hit_index = 0
    self.position = 0
    self.bind('<KeyRelease>', self.handle_keyrelease)               

def autocomplete(self, delta=0):
    if delta:
        self.delete(self.position, Tkinter.END)
    else:
        self.position = len(self.get())
    _hits = []
    for element in self._completion_list:
        if element.startswith(self.get().lower()):
            _hits.append(element)
            if _hits != self._hits:
                    self._hit_index = 0
                    self._hits=_hits
    if _hits == self._hits and self._hits:
            self._hit_index = (self._hit_index + delta) % len(self._hits)
    if self._hits:
            self.delete(0,Tkinter.END)
            self.insert(0,self._hits[self._hit_index])
            self.select_range(self.position,Tkinter.END)

def handle_keyrelease(self, event):
    if len(event.keysym)== 1:
        self.autocomplete()

if __name__ == '__main__':
    test_list = ('test', 'type', 'true', 'tree')
    root = Tkinter.Tk()
    entry = AutocompleteEntry(root)
    entry.set_completion_list(test_list)
    entry.pack()
    entry.focus_set()
    root.mainloop()

Обе эти программы отлично работают в одиночку, но у меня есть несколько проблем, связанных с их интеграцией, не последняя из которых состоит в том, чтобы отличать импорт Tkinter * / root = Tk () и импорт Tkinter / root = Tkinter.Tk (). Я думал, что это всего лишь два способа выразить одно и то же?

Что касается кодового класса, комбинированного класса-виджета, то какой более крупный фреймворк мне нужен, чтобы разбить эти два вместе? Должен ли я сделать один базовый класс, а другой наследовать? Должен ли я просто сложить их друг на друга с двумя корнями? Должен ли я сделать их оба класса под большим супер-классом?

ОБНОВЛЕННЫЕ КОМБИНИРОВАННЫЕ КЛАССЫ

from Tkinter import*

class AutocompleteEntry(Entry):

def set_completion_list(self, completion_list):
    self._completion_list = completion_list
    self._hits = []
    self._hit_index = 0
    self.position = 0
    self.bind('<KeyRelease>', self.handle_keyrelease)               

def autocomplete(self, delta=0):
    if delta:
        self.delete(self.position,END)
    else:
        self.position = len(self.get())
    _hits = []
    for element in self._completion_list:
        if element.startswith(self.get().lower()):
            _hits.append(element)
            if _hits != self._hits:
                    self._hit_index = 0
                    self._hits=_hits
    if _hits == self._hits and self._hits:
            self._hit_index = (self._hit_index + delta) % len(self._hits)
    if self._hits:
            self.delete(0,END)
            self.insert(0,self._hits[self._hit_index])
            self.select_range(self.position,END)

def handle_keyrelease(self, event):
    if len(event.keysym)== 1:
        self.autocomplete()

class Code:
def __init__(self, parent):
    self.myParent = parent
    self.main_frame = Frame(parent, background="light blue")
    self.main_frame.pack(expand=YES, fill=BOTH)

    test_list = ('test', 'type', 'true', 'tree')

    self.enter = AutocompleteEntry(self.main_frame, width=30)
    self.enter.set_completion_list(test_list)
    self.enter.pack(side=LEFT, expand=NO)

root = Tk()
code = Code(root)
root.mainloop()

1 Ответ

0 голосов
/ 19 января 2012

from Tkinter import *; root=Tk() и import Tkinter; root=Tkinter.Tk() являются более или менее двумя способами выразить одно и то же.По крайней мере, оба дают вам корневое окно.Однако они не совсем эквивалентны.Первый импортирует тонну вещей в пространство имен, а второй импортирует только одну вещь.

В Интернете я вижу много примеров, которые делают from Tkinter import *, но я думаю, что это плохая идея.Я предпочитаю import Tkinter as tk, который (a) не загрязняет пространство имен, (b) требует минимальных изменений при обновлении до python 3, и (c) очень ясно дает понять, когда вы вызываете функции Tkinter, а когда нет.

Что касается вашего вопроса о наличии двух корней ... Нет, не делайте этого.Вы можете иметь только один экземпляр класса Tk в приложении.Чтобы использовать их вместе, либо импортируйте их отдельно (т. Е. Не копируйте и не вставляйте их в один файл), либо вам придется изменить один или другой, чтобы они использовали одну и ту же стратегию импорта.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...