Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » GUI
  • » PyGTK получение текущего размера виджета [RSS Feed]

#1 Окт. 18, 2012 06:46:45

@cckyi_boxxx
От:
Зарегистрирован: 2012-01-13
Сообщения: 181
Репутация: +  14  -
Профиль   Отправить e-mail  

PyGTK получение текущего размера виджета

набросал левый код что-бы отобразить суть вопроса

import gtk
win = gtk.Window()
win.set_size_request(500 , 500)
win.show()
win.connect("delete_event" , gtk.main_quit)
# лайоут для компоновки виджетов
lay = gtk.Layout()
lay.set_size(500 , 500)
lay.show()
win.add(lay)
# текстовое поле высота (height) которого могут быть произвольными а длина фиксированная + включен автоперенос по словам
txt = gtk.TextView()
txt.set_size_request(400 , -1)
txt.set_wrap_mode(gtk.WRAP_WORD)
txt.show()
lay.put(txt , 50 , 50)
# получаю буффер для вставки текста
buf = txt.get_buffer()
# длинный текст неизвестной заранее длины 
long_text = "rbir rb rtb rtb rtb tr b rt hgrthg rthg \n\n\n\n\n\n\n\n brtrtigirbtntr \
ibrtnritnitrb rtbrthb rthg tr4hgrt\n\n\n\n ergierbgiueb te \n eigbreigeigun \n\n\n\n\n \
tebnpblorb tronhgitrnoihgntr gtriohnjjoirt btroihjgoitrh ntrhjitr"
buf.set_text(long_text)
gtk.main()

а вопрос таков : после вставки текста в textview его высота измениться , а что-бы размещать виджеты под ним мне надо получить его размеры в пикселях , как это сделать ?



Офлайн

#2 Окт. 21, 2012 03:09:29

@cckyi_boxxx
От:
Зарегистрирован: 2012-01-13
Сообщения: 181
Репутация: +  14  -
Профиль   Отправить e-mail  

PyGTK получение текущего размера виджета

вобщем оказалось все не так просто как хотелось-бы :

для начала поясню суть приложения -
1) с сервера загружаеться инфа (текст рандомной длины)
2) в gtk.Layout() вставляеться gtk.TextView постоянной длины но переменной высоты wrap mode - перенос по словам
3) полученный текст разбиваеться на несколько частей и отформатированный при помощи gtk.TextTag инсертиться в несколько заходов в gtk.TextView
4) определив длину gtk.TextView после вставки текста под ним тыкаються несколько кнопок и полей ввода (gtk.Entry)
5) все повторяеться для каждого полученного с сервера текста (их кол-во динамическое)

а теперь к техническим вопросам :

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

self._agtview.connect("size-request" , self._alloc) # self._agtview обьект класса gtk.TextView
def _alloc(self , widget , allocation):
    self.__chey = allocation.height
    self.__cwid = allocation.width
    print allocation.width , ' hey = ' , allocation.height

принт заюзан в функции для того что-бы видеть что выдает аллокэйшен , и он выдает все верно но есть одно но - событие “size-request” выскакивает несколько раз , ниже привожу вывод от принта

192 hey = 255
664 hey = 255
664 hey = 323

из него видно что высота увеличиваеться (что логично при добавлении текста) но это создает проблему так как мне нужно получить конечную высоту и уже от нее отсчитав 10 пикселей располагать следующий виджет , но каким образом спалить то что это была последняя сработка “size-request” я не знаю , мб кто-нибудь подскажет выход из положения



Отредактировано @cckyi_boxxx (Окт. 21, 2012 03:10:43)

Офлайн

#3 Окт. 21, 2012 09:31:52

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

PyGTK получение текущего размера виджета

Я с GTK не сталкивался, но разве там нет Layout'ов как в Qt? Задаем взаимное расположение виджетов и правила ресайза, а компоновщик пускай сам считает все размеры.

Вроде оно:
http://www.pygtk.org/pygtk2tutorial/ch-PackingWidgets.html

Офлайн

#4 Окт. 21, 2012 15:16:00

@cckyi_boxxx
От:
Зарегистрирован: 2012-01-13
Сообщения: 181
Репутация: +  14  -
Профиль   Отправить e-mail  

PyGTK получение текущего размера виджета

есть лайоуты , как раз ими и пользуюсь , и с ресайзом проблем нет , а вот что сделать с компоновкой виджетов это вопрос , так как втыкая виджет нужно указывать куда его воткнуть , а для этого требуеться знать сколько места занял предидущий виджет

если лепить layout.put(widget , -1 , -1) надеясь на то что компоновщик сообразит что следующий виджет следует расположить под предидущим - ничего не выходит и он лепит его по координатам (0 , 0)



Офлайн

#5 Окт. 21, 2012 15:53:03

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

PyGTK получение текущего размера виджета

Я так понял в GTK layout - это как scroll area. Вы по ссылке ходили? Там не он используется, а VBox и HBox.

import gtk
win = gtk.Window()
win.set_size_request(500 , 500)
win.show()
win.connect("delete_event" , gtk.main_quit)
 
txt = gtk.TextView()
txt.set_size_request(400 , -1)
txt.set_wrap_mode(gtk.WRAP_WORD)
txt.show()
button1 = gtk.Button("button1")
button1.show()
button2 = gtk.Button("button2")
button2.show()
 
box = gtk.VBox(False, 0)
box.show()
box.pack_start(txt)
box.pack_start(button1)
box.pack_start(button2)
lay = gtk.Layout()
lay.set_size(500 , 500)
lay.show()
lay.put(box, 50, 50)
win.add(lay)
 
buf = txt.get_buffer()
long_text = "rbir rb rtb rtb rtb tr b rt hgrthg rthg \n\n\n\n\n\n\n\n brtrtigirbtntr \
ibrtnritnitrb rtbrthb rthg tr4hgrt\n\n\n\n ergierbgiueb te \n eigbreigeigun \n\n\n\n\n \
tebnpblorb tronhgitrnoihgntr gtriohnjjoirt btroihjgoitrh ntrhjitr"
buf.set_text(long_text)
gtk.main()

Офлайн

#6 Окт. 21, 2012 18:45:54

@cckyi_boxxx
От:
Зарегистрирован: 2012-01-13
Сообщения: 181
Репутация: +  14  -
Профиль   Отправить e-mail  

PyGTK получение текущего размера виджета

да спасибо я по ссылке ходил и это мне очень сильно помогло так как мне теперь достаточно вычислить размер всего одного единственного элемента - vbox

в gtk Layout изначально не имеет скроллбара но я нашел способ его туда прикрутить и перенаправлять scroll_event на скроллбар , только заквоздка в том что если не задать размер gtk.Layout явно , при помощи set_size() то скроллинг отваливаеться

import gtk
# вывожу изменения размера
def ff(w , a):
    print 'width : ' , a.width , ' height : ' , a.height
# проброс событий из эвентбокса к скроллбару
def scr(w , e):
    scroll.do_scroll_event(scroll , e)
win = gtk.Window()
win.set_size_request(500 , 500)
win.show()
win.connect("delete_event" , gtk.main_quit)
 
txt = gtk.TextView()
txt.set_size_request(400 , -1)
txt.set_wrap_mode(gtk.WRAP_WORD)
txt.show()
button1 = gtk.Button("button1")
button1.show()
button2 = gtk.Button("button2")
button2.show()
 
box = gtk.VBox(False, 0)
box.show()
box.pack_start(txt)
box.pack_start(button1)
box.pack_start(button2)
box.connect("size-request" , ff)
lay = gtk.Layout()
lay.set_size(400 , 1000) # высота лайоута больше чем высота окна но самое основное что она задана явно !
lay.show()
lay.put(box, 50, 50)
# запиливаю контейнер который служит для проброса событий
evbox = gtk.EventBox()
evbox.show()
evbox.set_events(gtk.gdk.SCROLL_MASK)
evbox.connect("scroll_event" , scr)
evbox.add(lay)
# создание скроллбара привязанного к текстовому виджету
scroll = gtk.VScrollbar(lay.get_vadjustment())
scroll.show()
# не скроллящийся элемент для выдачи какой-либо инфы юзверю
info = gtk.Label('trololo')
info.show()
info.set_size_request(200 , 20)
# при помощи этой таблицы втыкаю все добро в окно
table = gtk.Table(2, 2, False)
table.attach(evbox, 0, 1, 0, 1, gtk.FILL | gtk.EXPAND, gtk.FILL | gtk.EXPAND)
table.attach(scroll, 1, 2, 0, 1, gtk.FILL | gtk.SHRINK, gtk.FILL | gtk.SHRINK)
table.attach(info, 0, 1, 1, 2, gtk.FILL | gtk.SHRINK, gtk.FILL | gtk.SHRINK)
table.set_size_request(500 , 500)
table.show()
win.add(table)
buf = txt.get_buffer()
long_text = "rbir rb rtb rtb rtb tr b rt hgrthg rthg \n\n\n\n\n\n\n\n brtrtigirbtntr \
ibrtnritnitrb rtbrthb rthg tr4hgrt\n\n\n\n ergierbgiueb te \n eigbreigeigun \n\n\n\n\n \
tebnpblorb tronhgitrnoihgntr gtriohnjjoirt btroihjgoitrh ntrhjitr"
buf.set_text(long_text)
gtk.main()

вот образец того что я сделал , так если заменить
lay.set_size(400 , 1000)
на
lay.set_size(-1 , -1)
то скроллинг отваливаеться , да и виджеты не показываються

ps: -1 -1 служат для того что-бы компоновщик автоматически определил величину

вывод прост - vbox упрощает задачу тем что теперь надо определить конечный размер только одного виджета а не так как планировалось ранее (все TextView) но проблема остаеться в том что я не знаю какое по счету событие “size-request” являеться последним , ибо только на последнем этом событии vbox приобретает конечный размер о чем четко сообщает функция ff() , вот ее вывод :

width :  400  height :  260
width :  400  height :  260
width :  400  height :  335

задача после получения конечного значения height запилить
lay.set_size(400 , height)

и вот над реализацией этой задачи я и ковыряюсь но пока ничего здравого в голову не приходит , надеюсь придет кому-то из юзеров форума , всем спс



Офлайн

#7 Окт. 21, 2012 22:25:45

@cckyi_boxxx
От:
Зарегистрирован: 2012-01-13
Сообщения: 181
Репутация: +  14  -
Профиль   Отправить e-mail  

PyGTK получение текущего размера виджета

################# upd ######################
я сказочный долбаеб , запилил тупо ресайз при каждом событии “size-request” и все заработало , просто размер увеличиваеться постепенно а не одним рывком , еще раз спасибо всем за внимание , вопрос решен .



Офлайн

  • Начало
  • » GUI
  • » PyGTK получение текущего размера виджета[RSS Feed]

Board footer

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

Powered by DjangoBB

Lo-Fi Version