2016-10-09 3 views
3

Я пытался изменить размер метки на некоторое время, но это кажется НЕВОЗМОЖНЫМ или, по крайней мере, непостижимым для меня ...Как изменить размер метки?

Я объясню свою ситуацию с изображениями для ясности.

enter image description here

Это как окно выглядит с ярлыком "Normal" ...

enter image description here

Это как окно выглядит с смехотворно большим текстом ...

enter image description here

Так вот, как я хочу, чтобы это выглядело, когда текст смехотворно l arge

См.?

Вот пример кода:

# -*- coding: utf-8 -*- 

import gi 
import signal 
import hashlib 
import random 
gi.require_version("Gtk", "3.0") 
from gi.repository import Gtk, Pango 

class Test(Gtk.Window): 
    def __init__(self): 
     def center(a): 
      a.props.valign = Gtk.Align.CENTER 
      a.props.halign = Gtk.Align.CENTER 
     Gtk.Window.__init__(self, title="Test") 
     self.set_position(Gtk.WindowPosition.CENTER) 
     self.set_border_width(10) 
     self.set_resizable(False) 
     self.connect("delete-event", Gtk.main_quit) 

     Box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) 
     Button = Gtk.Button("Change Label") 
     Label = Gtk.Label() 

     Test = "I'm a Label, Yay!" 

     center(Box) 
     center(Label) 
     center(Button) 

     Label.set_markup('<span><big>%s</big></span>' % Test) 
     Label.set_ellipsize(Pango.EllipsizeMode.END) 
     Label.set_justify(Gtk.Justification.LEFT) 

     self.add(Box) 

     Box.add(Label) 
     Box.add(Button) 

     #UNKNOWN/FORBIDDEN/DEPRECIATED/INCOMPREHENSIBLE MAGIC! 
      #Uncomment only one or both, and watch it's magic! 

     #self.set_resizable(True) 
     #Box.set_resize_mode(Gtk.ResizeMode.QUEUE) 

     def change_label(self): 
      Label.set_markup('<span><big>%s</big></span>' % str(hashlib.sha384(str(random.random())).hexdigest())) 

     Button.connect("clicked", change_label) 

if __name__ == '__main__': 
    MainWindow = Test() 
    MainWindow.show_all() 
    signal.signal(signal.SIGINT, signal.SIG_DFL) 
    Gtk.main() 

Пожалуйста, обратите внимание, что окно не изменяемыми.

Если вы раскомментируете один или оба раздела «Магия», вы увидите, как изменится его поведение Window!

НО

Есть два недостатка во время использования каждого из этого подходит:

  • Если раскомментировать #self.set_resizable(True) ОКНО СТАНЕТ перезначительном РАЗ, которые я не хочу, чтобы это произошло

  • #Box.set_resize_mode(Gtk.ResizeMode.QUEUE) представляется идеальным решением, но в то время как он делает то, что я хочу, кажется, он был «изношен» в последних версиях Gtk.

Кроме того, в некоторых других оконных менеджеров & темы, это вызывает некоторые сбои на габаритах окна при смене лейбла Струнный много раз.

У вас есть предложения по этому вопросу?

Я полностью устал от этого. Я пытаюсь в течение нескольких недель, без результата: c

Возможно, есть способ подражать поведению при изменении размера окна, а не показе Resize Grips & Maximize Button?

Или что нового метода set_resize_mode(Gtk.ResizeMode.QUEUE)?

PD: Label.set_max_width_chars() не то, что я ищу

+0

Можете ли вы объяснить, почему 'set_max_width_chars()' не опция? –

+0

Потому что это ограничивает слова до указанной длины, которую вы запросили. Это будет работать в некоторых случаях, но давайте представим, что вы можете добавить немецкий перевод. Например, на английском языке вы можете установить текст ярлыка «awesome» и «Label.set_max_width_chars» (7). На немецком языке текст Label будет «Ehrfurcht gebietend» (по крайней мере, это сказал Google Translator). – PythonNoob

+0

Я понял. Нельзя ли использовать длину строки для установки значения ширины так, чтобы она соответствовала исходному тексту, а затем, если метка изменена, ширина остается неизменной. –

ответ

1

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

Вот что я сделал:

  • С 1 ° методы, я удалил «хак» код
  • Затем я добавил «Мини-Box» объект, который является Gtk.ButtonBox (Специальный вид коробки ...) и установите его как «Однородный»
  • Впоследствии я удалил объект «Button» из «Ящика» и добавил «Ярлык» & «Кнопка» объектов в «Мини-бокс» "
  • Не говоря уже о том, что мне пришлось добавить« мини-коробку »в« коробку »тоже ...

Выполнено!

Вот пример кода:

#!/usr/bin/python2 

# -*- coding: utf-8 -*- 

import gi 
import signal 
import hashlib 
import random 
import time 
gi.require_version("Gtk", "3.0") 
from gi.repository import Gtk, Pango 

class TestWindow(Gtk.Window): 

    def __init__(self): 

     Gtk.Window.__init__(self, title="Test") 
     self.set_position(Gtk.WindowPosition.CENTER) 
     self.set_border_width(10) 
     self.set_resizable(False) 
     self.connect("delete-event", Gtk.main_quit) 

     ##Declare Objects 

     #Boxes 
     Box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) 
     Mini_Box = Gtk.ButtonBox(orientation=Gtk.Orientation.HORIZONTAL, spacing=10, homogeneous=True) 

     #Buttons 
     Button = Gtk.Button.new_with_mnemonic("_Randomize Label") 

     #Labels 
     Label = Gtk.Label() 

     #Variables & Misc 
     Test = "I'm a Label, Yay!" #Label's width should NOT be larger than the Button's size to be displayed entirely, though... 

     ##Change Objects Properties 

     #Alignments 
     self.center(Box) 

     #Labels 
     Label.set_markup('<span><big>%s</big></span>' % Test) 
     Label.set_ellipsize(Pango.EllipsizeMode.END) 
     Label.set_justify(Gtk.Justification.LEFT) 

     ##Packaging 

     #Boxes 
     self.add(Box) 

     Box.add(Mini_Box) 
     Mini_Box.add(Label) 
     Mini_Box.add(Button) 

     def change_label(self): 
      Label.set_markup('<span><big>%s</big></span>' % str(hashlib.sha384(str(random.random())).hexdigest()).rstrip()) 

     Button.connect("clicked", change_label) 

    def center(self, object): 
     object.props.valign = Gtk.Align.CENTER 
     object.props.halign = Gtk.Align.CENTER 

if __name__ == '__main__': 
    MainWindow = TestWindow() 
    MainWindow.show_all() 
    signal.signal(signal.SIGINT, signal.SIG_DFL) 
    Gtk.main() 

не будет размещать новые скриншоты, потому что результат будет таким же, как и выше ...

+0

Я думаю, что это будет мой «окончательный» ответ на эту тему. Положите это так, чтобы люди прочитали это первым – PythonNoob

2

Вы можете прочитать о рамке часы в Gtk 3.12. Вот хороший article. Новый способ использования очереди для изменения размера - Gtk.Widget.queue_resize()

Если некоторые изменения состояния, что вызывает размер виджета, чтобы изменить вызов gtk_widget_queue_resize(), который будет запрашивать фазы макета и маркировать свой виджет как нуждаясь relayout.

Я считаю, что измененный пример кода ниже делает то, что вы хотите. Трюк состоит в том, чтобы иметь подпапки для включения Gtk.Label и Gtk.Button. Затем установите max_width_chars в 1, ellipsize к END, hexpand к True и halign к FILL на этикетке.

import signal 
import hashlib 
import random 
gi.require_version("Gtk", "3.0") 
from gi.repository import Gtk, Pango 

class Test(Gtk.Window): 
    def __init__(self): 
     Gtk.Window.__init__(self, title="Test") 
     self.set_size_request(250,-1) 
     self.set_position(Gtk.WindowPosition.CENTER) 
     self.set_border_width(10) 
     self.set_resizable(False) 
     self.connect("delete-event", Gtk.main_quit) 

     Box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) 
     Sub_box_left = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) 
     Sub_box_right = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) 
     Button = Gtk.Button("Change Label") 
     Label = Gtk.Label() 

     Test = "I'm a Label, Yay!" 

     Label.set_markup('<span><big>%s</big></span>' % Test) 
     Label.set_max_width_chars(1) 
     Label.set_ellipsize(Pango.EllipsizeMode.END) 
     Label.set_hexpand(True) 
     Label.props.halign = Gtk.Align.FILL 
     Label.set_justify(Gtk.Justification.LEFT) 

     self.add(Box) 

     Sub_box_left.add(Label) 
     Sub_box_right.add(Button) 

     Box.add(Sub_box_left) 
     Box.add(Sub_box_right) 

     def change_label(self): 
      Label.set_markup('<span><big>%s</big></span>'%str(hashlib.sha384(str(random.random())).hexdigest())) 

     Button.connect("clicked", change_label) 

if __name__ == '__main__': 
    MainWindow = Test() 
    MainWindow.show_all() 
    signal.signal(signal.SIGINT, signal.SIG_DFL) 
    Gtk.main() 
+0

Нет, не получится – PythonNoob

+1

Я отредактировал свой ответ в соответствии с обсуждением выше. Надеюсь, это то, чего вы хотите достичь. –

+0

Действительно, это был хороший подход. Я решил проанализировать оба кода и обнаружил, что вы действительно можете изменить еще меньше «Мой» код, чтобы достичь того, что у вас есть. – PythonNoob

0

Ну, немного подумав, я нашел «хакерский» способ достичь того, что я пытался.

Я попытаюсь это объяснить словами, а потом I'l, выкладываю «Final» код, но я убежден, что это может быть оптимизирован, или, по крайней мере, это то, что я надеюсь :)

То, что я сделал, должен был взять оба кода, (Оригинал & Модифицированная версия Жака Годена), проанализировать их и создать менее сложную версию.

Тогда я понял, что модификации Жака Годена сделали Window set_size_request зависимым от разработчика, поскольку он подбирал ширину и высоту.

В качестве «обходного» я ​​решил сделать следующее:

  • Чистый код
  • Пусть окно «появляются» без ограничений, поэтому он может рассчитать точную ширину и высоту, необходимую для него в правильно отображать и скрывать окно, чтобы избежать слишком быстрого нажатия кнопки «Рандомизировать».
  • После того, как окно сокрыло себя, запросить его точные значения (ширина & высоты)
  • После того, как собраны эти значения, в то время как окно по-прежнему скрыто, повторно объявить MainWindow объект, но на этот раз меняет свои аргументы (None, None) к ранее собранным значениям: (Width, Height)
  • Далее, окну нужно будет пересчитать некоторые внутренние ценности, как следствие изменять свои аргументы
  • Наконец, когда окно завершения повторного вычисления значений, он показывает себя снова, НО на этот раз с желаемой шириной & Высота для отображения propely AND e если по какой-то причине ярлык растет, Окно останется с тем же размером.

Я знаю, что это не «лучший» ответ, но по крайней мере он работает.

К сожалению, есть несколько вопросов, оставшихся:

  • Как мы могли «центр» ярлык?
  • Если этот метод используется в медленных машинах, возможно ли, что окно будет медленным при скрытии, вызывая какую-то ошибку/сбой, если пользователь нажимает кнопку «Рандомизировать» yoo раньше?
  • А как насчет динамических переводов текста?Могут ли они быть даже возможными без необходимости «перезапуска» окна? (Ну, это не будет большой проблемой, но все же любопытно подумать ...)
  • ЕСТЬ ЛИ ЛЮБЫЕ ПУТИ, ЧТОБЫ ДОСТУПИТЬ ЭТО? (Самый важный вопрос: с)

Вот код:

#!/usr/bin/python2 

# -*- coding: utf-8 -*- 

import gi 
import signal 
import hashlib 
import random 
gi.require_version("Gtk", "3.0") 
from gi.repository import Gtk, Pango 

class TestWindow(Gtk.Window): 

    def __init__(self, width, height): 

     if width is None: 
      width = -1 

     if height is None: 
      height = -1 

     Gtk.Window.__init__(self, title="Test") 
     self.set_position(Gtk.WindowPosition.CENTER) 
     self.set_border_width(10) 
     self.set_resizable(False) 
     self.set_size_request(width, height) 
     self.connect("delete-event", Gtk.main_quit) 

     ##Declare Objects 

     #Boxes 
     Box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL, spacing=10) 

     #Buttons 
     Button = Gtk.Button.new_with_mnemonic("Randomize Label") 

     #Labels 
     Label = Gtk.Label() 

     #Variables & Misc 
     Test = "I'm a Label, Yay!" #You can change me for a bigger label if you want 

     ##Change Objects Properties 

     #Alignments (Could break things...) 
     #self.center(Box) 
     #self.center(Label) 
     #self.center(Button) 

     #Labels 
     Label.set_markup('<span><big>%s</big></span>' % Test) 
     Label.set_ellipsize(Pango.EllipsizeMode.END) 

     if width is not -1: 
      Label.set_max_width_chars(1) 

     Label.set_justify(Gtk.Justification.FILL) 

     ##Packaging 

     #Boxes 
     self.add(Box) 

     Box.pack_start(Label, True, True, 0) 
     Box.add(Button) 

     def change_label(self): 
      Label.set_markup('<span><big>%s</big></span>' % str(hashlib.sha384(str(random.random())).hexdigest())) 

     Button.connect("clicked", change_label) 

    def center(self, object): 
     object.props.valign = Gtk.Align.CENTER 
     object.props.halign = Gtk.Align.CENTER 

if __name__ == '__main__': 
    MainWindow = TestWindow(None, None) 
    MainWindow.show_all() 
    MainWindow.hide() 
    Width, Height = MainWindow.get_size() 
    MainWindow = TestWindow(Width, Height) 
    MainWindow.show_all() 
    signal.signal(signal.SIGINT, signal.SIG_DFL) 
    Gtk.main() 

Вот несколько скриншотов:

enter image description here

Это "Перед" нажатием на кнопку .. .

enter image description here

Это «после» нажатие кнопки ...

+0

Некоторая обратная связь не повредит, хе-хе ... – PythonNoob

Смежные вопросы