Уведомления

Группа в Telegram: @pythonsu

#1 Апрель 16, 2014 09:58:03

4kpt_II
От: Харьков
Зарегистрирован: 2013-10-24
Сообщения: 999
Репутация: +  58  -
Профиль   Отправить e-mail  

Tkinter. Метод bind() и метод get()

Убегаю. Вечером отпишусь.

Офлайн

#2 Апрель 16, 2014 10:08:18

MetalHead
От: Ленгер
Зарегистрирован: 2013-12-17
Сообщения: 88
Репутация: +  1  -
Профиль   Отправить e-mail  

Tkinter. Метод bind() и метод get()

Хорошо, буду ждать, удачи

Офлайн

#3 Апрель 16, 2014 21:11:52

4kpt_II
От: Харьков
Зарегистрирован: 2013-10-24
Сообщения: 999
Репутация: +  58  -
Профиль   Отправить e-mail  

Tkinter. Метод bind() и метод get()

В принципе можно и так.
Тогда используем механизм:

if event.widget["text"] in ["*", "/", "-", "+"]:
    if self.ent.get()[-1] in [str(i) for i in xrange(10)]:
        ent.set("end", event.widget["text"])

Но в этом случае Вам придется написать дополнительное условие для “=”.

P.S. Будут вопросы - пишите …

Офлайн

#4 Апрель 20, 2014 11:34:06

MetalHead
От: Ленгер
Зарегистрирован: 2013-12-17
Сообщения: 88
Репутация: +  1  -
Профиль   Отправить e-mail  

Tkinter. Метод bind() и метод get()

Извиняюсь за молчание только руки дошли, пробовал ваши советы, подумал сам и в итоге нашел простейший выход:

from tkinter import *
class Buts:
    def __init__(self):
        but_minus = Button(root, text="-")
        but_plus = Button(root, text="+")
        num = Button(root, text=1)
        num2 = Button(root, text=2)
        num3 = Button(root, text=3)
        but_minus.bind("<Button-1>", self.click_on)
        but_plus.bind("<Button-1>", self.click_on)
        num.bind("<Button-1>", self.click_on)
        num2.bind("<Button-1>", self.click_on)
        num3.bind("<Button-1>", self.click_on)
        but_minus.pack(), but_plus.pack(), num.pack()
        num2.pack(), num3.pack()
        self.ent = Entry(root)
        self.ent.pack()
        self.this_last = int() # переменная типа int(), она и играет роль
    def click_on(self,event):
        if isinstance(event.widget["text"], str):
            if isinstance(self.this_last, str):
                self.ent.insert(END, event.widget["text"])
                self.this_last = int() # блокируем знаки      
        if isinstance(event.widget["text"], int):
            self.ent.insert(END, event.widget["text"])
            self.this_last = str() # снимаем блокировку
root = Tk()
obj = Buts()
root.mainloop()
Еще один вопрос, можно ли заблокировать виджет Entry() от ввода с клавиатуры?

Отредактировано MetalHead (Апрель 20, 2014 11:34:34)

Офлайн

#5 Апрель 20, 2014 12:48:36

4kpt_II
От: Харьков
Зарегистрирован: 2013-10-24
Сообщения: 999
Репутация: +  58  -
Профиль   Отправить e-mail  

Tkinter. Метод bind() и метод get()

Ой-йой-йой…

Смотрите. У Вас набрались ошибки в коде:

1. Если для построения GUI используем ООП, то надо наследовать от рамки, т.е.

class Buts (tkinter.Frame):
#
    def __init__(self, root=None):
        super().__init__(self, root)
        self.pack()

В этом случае главная рамка будет доступна в классе как self.

2. Этого делать никогда нельзя!!!

from tkinter import *

Прочитать, почему можно вот здесь…

3. Если у Вас много однотипных виджетов, то проще создавать и упаковывать их в цикле:

self.buttons_number = {}
name = [("7", "8", "9"), ("4", "5", "6"), ("1", "2", "3")]
for _ in name:
    frm = tkinter.Frame(self)
    frm.pack()
    for btext in name:
        but_vr = tkinter.Button(frm, text=btext)
        but_vr.bind("<ButtonRelease-1>", call)  # функция call описана в проблеме ниже :)
        but_vr.pack(side="left")
        self.buttons_numbers[btext] = but_vr

Таким образом у Вас получаются, что все ссылки на кнопки с цифрами собраны в словаре buttons_number, где ключом является текст внутри кнопки, а значением - ссылка на кнопку (которую можно дальше использовать). Такой же словарь для кнопок операций (только называете его, например, self.buttons_operations) тоже можно создать в цикле.

4. Вы меня явно не поняли Это не простое решение - это костыль. Простое решение я Вам написал, но могу повторить.

def call(event):
    if event.widget in self.button_operations.values():  # проверяем, что нажата одна из операций  
        if self.ent.get[-1] in [str(i) for i in range(10)]:  # проверяем, что до нажатия операции в ent есть цифры использую индекс [-1]
            self.ent.insert("end", event.widget["text"])  # добавляем в конец ent надпись на кнопке операций (* или - или + или /)
    else:  # нажата не кнопка операций, а просто кнопка цифр
        self.ent.insert("end", event.widget["text"])  # вставляем в конец ent надпись на кнопке цифр

5. Заблокировать self.ent можно, указав для свойства “state” в значение “disabled”. Только тогда необходимо поиграться со свойствами “disabledbackground” и “disabledforeground” для того, чтобы при “state” = “disabled” self.ent выглядел так, как будто у него “state” = “normal” и не был серого цвета.
Единственное. В этом случае необходимо перед вставкой включать self.ent и после вставки данных выключать self.ent., т.е. функция приобретет вид:

def call(event):
    if event.widget in self.button_operations_numbers.values(): 
        if self.ent.get[-1] in [str(i) for i in range(10)]:
            self.ent["state"] = "normal"  # включаем, чтобы вставить виджет
            self.ent.insert("end", event.widget["text"])
            self.ent["state"] = "disabled"  # снова блокируем
    else:
        self.ent["state"] = "normal"
        self.ent.insert("end", event.widget["text"])
        self.ent["state"] = "disabled"

Чтобы не играться со свойствами “disabledbackground” и “disabledforeground” можно использовать другое состояние (“readonly”). В этом случае тоже необходимо включать и выключать состояние в функции call, но виджет при отключении выглядит так же, как и при “state” = “normal”, т.е. не “сереет”.

P.S. Будут вопросы - пишите…

Отредактировано 4kpt_II (Апрель 20, 2014 13:15:09)

Офлайн

#6 Апрель 20, 2014 13:19:22

MetalHead
От: Ленгер
Зарегистрирован: 2013-12-17
Сообщения: 88
Репутация: +  1  -
Профиль   Отправить e-mail  

Tkinter. Метод bind() и метод get()

4kpt_II
1. Если для построения GUI используем ООП, то надо наследовать от рамки, т.е.
Я так понимаю для каждого виджета нужен будет свой класс?
За остальное спасибо, радует, что есть такие отзывчивые люди, которые без заумностей могут объяснить как все работает.

Офлайн

#7 Апрель 20, 2014 15:39:57

4kpt_II
От: Харьков
Зарегистрирован: 2013-10-24
Сообщения: 999
Репутация: +  58  -
Профиль   Отправить e-mail  

Tkinter. Метод bind() и метод get()

MetalHead
Я так понимаю для каждого виджета нужен будет свой класс?

Для обособленной группы виджетов.
Например, отдельный класс для таблицы, которую я себе когда-то собрал. Там множество листбоксов и полос прокрутки. Делаю экземпляр класса и потом располагаю наследуемый фрейм вместе со всеми листбоксами и полосами прокрутки в нужном месте, как то-так:

table = MyTable(root)  # класс с наследуемым Frame
table.grid(row=1, column=1)  # располагаем все виджеты этого класса в нужном нам месте

Так, как мы наследовали от рамки, то размещается просто рамка со всем содержимым одной командой.

P.S. Будут вопросы - пишите…

Отредактировано 4kpt_II (Апрель 20, 2014 15:40:37)

Офлайн

#8 Апрель 21, 2014 07:39:39

MetalHead
От: Ленгер
Зарегистрирован: 2013-12-17
Сообщения: 88
Репутация: +  1  -
Профиль   Отправить e-mail  

Tkinter. Метод bind() и метод get()

Ага, все понятно, буду стараться придерживаться этих правил Вопросы исчерпаны.

Офлайн

#9 Апрель 24, 2014 14:10:17

Griffon
От: Ukrain, Zaporozhie
Зарегистрирован: 2009-03-04
Сообщения: 324
Репутация: +  11  -
Профиль   Отправить e-mail  

Tkinter. Метод bind() и метод get()

Как по мне так легче реализовать “если не цифра и дубль - удалить”, чем перебирать все варианты.



Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version