Уведомления

Группа в Telegram: @pythonsu

#1 Ноя. 20, 2014 01:31:55

Strelok-den
Зарегистрирован: 2014-03-25
Сообщения: 63
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter и Threading

4kpt_II
Ну с классом это Вы размахнулись Сегодня уже устал как собака. Задачу понял. Завтра выложу код.

Хорошо спасибо) буду ждать) надеюсь не слишком замудренно выйдет.. или таки придеться перейти на Qt(

Офлайн

#2 Ноя. 20, 2014 23:43:59

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

Tkinter и Threading

Держите. Постарался написать попроще

import Tkinter
import thread
#
flag = 1
number = 0
#
def my_thread():
    global flag
    while flag:
        pass
        # Вставляем сюда код, который должен выполняться в потоках
#
def gui_freedom():
    global number
    number += 1
    myLabel.config(text="number {0}".format(number))
    root.after(100, gui_freedom)
#
def freedom_click(event):
    print "I'm freedom :)"
#
def start(event):
    thread.start_new(my_thread, ())
#
def stop(event):
    global flag
    flag = None
#
root = Tkinter.Tk(className=" tester")
root.protocol("WM_DELETE", root.destroy)
#
myLabel = Tkinter.Label(root, text="ops")
myLabel.place(relx=0.5, rely=0.25, anchor="center")
#
but_press = Tkinter.Button(root, text="press")
but_press.place(relx=0.5, rely=0.5, anchor="center")
but_press.bind("<Button-1>", freedom_click)
#
but_start = Tkinter.Button(root, text="start")
but_start.place(relx=0.5, rely=0.7, anchor="center")
but_start.bind("<Button-1>", start)
#
but_stop = Tkinter.Button(root, text="stop")
but_stop.place(relx=0.5, rely=0.9, anchor="center")
but_stop.bind("<Button-1>", stop)
#
root.after(50, gui_freedom)
root.mainloop()

Отредактировано 4kpt_II (Ноя. 20, 2014 23:44:43)

Офлайн

#3 Ноя. 21, 2014 00:56:48

Strelok-den
Зарегистрирован: 2014-03-25
Сообщения: 63
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter и Threading

4kpt_II
Держите. Постарался написать попроще
import Tkinter
import thread
#
flag = 1
number = 0
#
def my_thread(): #с этим понятно
    global flag
    while flag:
        pass
        # Вставляем сюда код, который должен выполняться в потоках
#
def gui_freedom():
    global number
    number += 1
    myLabel.config(text="number {0}".format(number)) # это не понятно что делает(
    root.after(100, gui_freedom) # и это впринципи тоже...
#
def freedom_click(event):
    print "I'm freedom :)" # понятно
#
def start(event): # понятно
    thread.start_new(my_thread, ())
#
def stop(event): # понятно
    global flag
    flag = None
#
root = Tkinter.Tk(className=" tester") # не понятно
root.protocol("WM_DELETE", root.destroy) # понятно
#
myLabel = Tkinter.Label(root, text="ops") # понятно
myLabel.place(relx=0.5, rely=0.25, anchor="center") # понятно
#
but_press = Tkinter.Button(root, text="press") # понятно
but_press.place(relx=0.5, rely=0.5, anchor="center") # понятно
but_press.bind("<Button-1>", freedom_click) # понятно
#
but_start = Tkinter.Button(root, text="start") # понятно
but_start.place(relx=0.5, rely=0.7, anchor="center") # понятно
but_start.bind("<Button-1>", start) # понятно
#
but_stop = Tkinter.Button(root, text="stop") # понятно
but_stop.place(relx=0.5, rely=0.9, anchor="center") # понятно
but_stop.bind("<Button-1>", stop) # понятно
#
root.after(50, gui_freedom) # не понятно
root.mainloop() # понятно

ну общую конструкцию я понял.. но как быть с классами? и смножества гуи окнами? тогда?…

Переделывать 1200 кода строк с классами в код без классов довольно муторно.. можно как то тоже самое в классе реализовать? или Tkinter не позволят?

Как то так, сильно не бейте)

Офлайн

#4 Ноя. 21, 2014 01:08:23

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

Tkinter и Threading

У Вас нет там классов нормальных все равно А переделывать можно. Раз логику поняли, то попробуйте сами.

Но вот только со множеством окон не получится, если только это не будут окна без логики. Вам вряд-ли такое под силу Если есть какие-то процессы и нужно по ним выводить статус или результат, то лучше это делать через переменную number или как-то так. Хотя можете попробовать реализовать обмен данными между потоками и GUI и уже чтобы GUI реагировал на какие-то события выводом окон или еще чем-то…

Офлайн

#5 Ноя. 21, 2014 01:11:51

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

Tkinter и Threading

Кстати. Хотите разобраться как правильно воять GUI с ООП - почитайте учебные материалы от New Mexico Tech. Много интересного узнаете

Офлайн

#6 Ноя. 21, 2014 01:17:01

Strelok-den
Зарегистрирован: 2014-03-25
Сообщения: 63
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter и Threading

4kpt_II
У Вас нет там классов нормальных все равно А переделывать можно. Раз логику поняли, то попробуйте сами.

Попробую сам..) но как тогда должен выглядить нормальный класс? можно привести пример? я тогда уж сложу и попробую переделать) когда вообще его стоит использовать класс а когда нет?

Впринципи почему я во многом ушол от классов, что бы избавиться от глобал, так как говорят что это плохо…

Т/е у меня 3 варианта только?
1. Либо переделать код как в вашем примере
2. Либо отказаться от многопоточности и выпонять все гуи в одном потоке и выкидывать логику отдельно…
3. Или перейти на другую библиотеку..

Я все правильно понимаю?

П.С. какой вариант выбрали бы вы?)

Офлайн

#7 Ноя. 21, 2014 01:19:35

Strelok-den
Зарегистрирован: 2014-03-25
Сообщения: 63
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter и Threading

4kpt_II
Кстати. Хотите разобраться как правильно воять GUI с ООП - почитайте учебные материалы от New Mexico Tech. Много интересного узнаете

К сожалению я почти не знаю английского(

Офлайн

#8 Ноя. 21, 2014 02:08:19

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

Tkinter и Threading

Strelok-den
К сожалению я почти не знаю английского(

Читайте код. Просто просмотрите книгу и выберите и проанализируйте код.

Strelok-den
1. Либо переделать код как в вашем примере
2. Либо отказаться от многопоточности и выпонять все гуи в одном потоке и выкидывать логику отдельно…
3. Или перейти на другую библиотеку..

Я не знаю реальной задачи, поэтому не могу сказать точно.
Код переделывать придется в любом случае. Можно и в виде классов, но все равно переделывать. В общих чертах для решения я бы пробовал разработать какую-то схему обмена данными между отдельными потоками и базовым GUI. Делал бы я это, скорее всего, с использованием колбеков. Но это все гадание на кофейной гуще. Не зная реальной задачи сложно проектировать конкретное решение.

P.S. Можете просмотреть мои посты. Я там неоднократно приводил нормальный, с точки зрения ООП, код для Tkinter.

Офлайн

#9 Ноя. 26, 2014 12:59:50

Strelok-den
Зарегистрирован: 2014-03-25
Сообщения: 63
Репутация: +  0  -
Профиль   Отправить e-mail  

Tkinter и Threading

4kpt_II
Я не знаю реальной задачи, поэтому не могу сказать точно.
Код переделывать придется в любом случае. Можно и в виде классов, но все равно переделывать. В общих чертах для решения я бы пробовал разработать какую-то схему обмена данными между отдельными потоками и базовым GUI. Делал бы я это, скорее всего, с использованием колбеков. Но это все гадание на кофейной гуще. Не зная реальной задачи сложно проектировать конкретное решение.

P.S. Можете просмотреть мои посты. Я там неоднократно приводил нормальный, с точки зрения ООП, код для Tkinter.

Извините за задержку уезжал… А что если сделать так?
Сейчас главное окно реализовано так:
from tkinter import *#только для примера
class Application(Frame):
    def say_hi(self):
        print("hi there, everyone!")
        # и тут у меня вызывается какойто класс в новом потоке с гуи... 
        # грубо говоря
    def createWidgets(self):
        self.QUIT = Button(self)
        self.QUIT["text"] = "QUIT"
        self.QUIT["fg"] = "red"
        self.QUIT["command"] = self.quit
        self.QUIT.pack({"side": "left"})
        self.hi_there = Button(self)
        self.hi_there["text"] = "Hello",
        self.hi_there["command"] = self.say_hi
        self.hi_there.pack({"side": "left"})
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.createWidgets()
root = Tk()
app = Application(master=root)
app.mainloop()
root.destroy()

И переделать в:
from tkinter import *
class Rez():
    def f():
         self.a += self.a
   def __init__(self, a):
         self.a = a
         self.f()
         return self.a
class Application(Frame):
    def say_hi(self):
        print("hi there, everyone!")
        self.test()
    def createWidgets(self):
        self.QUIT = Button(self)
        self.QUIT["text"] = "QUIT"
        self.QUIT["fg"] = "red"
        self.QUIT["command"] = self.quit
        self.QUIT.pack({"side": "left"})
        self.hi_there = Button(self)
        self.hi_there["text"] = "Hello",
        self.hi_there["command"] = self.say_hi
        self.hi_there.pack({"side": "left"})
    def test(self):
        toplevel = Toplevel()
        toplevel.title("test")
        a = 1
        rezult = Rez(a)
        l1=Label(toplevel, text=rezult)
        l1.pack()
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.createWidgets()
root = Tk()
app = Application(master=root)
app.mainloop()
root.destroy()

Ерунда полная? или если улучшить то норм?)

Офлайн

#10 Ноя. 26, 2014 16:59:11

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

Tkinter и Threading

Нуууу, уже получше. Что плохо:
1. __init__ нужно всегда ставить первым методом.
2. Название l1, QUIT, a, f - не по PEP8.
3. Ну не все же элементы интерфейса нужно делать атрибутами… Только те, в которые нужен доступ из других методов. Хотя иногда их можно получить и по-другому: через event или родительский объект.
4. Frame.__init__(self, root) - это уже моветон. Лучше super(Application, self).__init__(master).
5. Когда Вы создаете объект, то сразу и назначайте его параметры:

but = tkinter.Button(self, bg="red", bd=4, widht=20)

Способ назначения по-типу словаря нужен, если внутри обработчика события Вам нужно поменять одно свойство. Если менять нужно много свойств, то лучше использовать .config(bg=“red”, width=10).

6. Никогда не используйте инструкцию!!!

from tkinter import *

В остальном код уже более-менее терпимый

Офлайн

Board footer

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

Powered by DjangoBB

Lo-Fi Version