如何调整标签宽度的大小?

时间:2016-10-09 22:34:54

标签: label size width gtk3 pygobject

我一直试图调整标签的宽度一段时间,但这似乎是不可能的,或者至少对我来说是不可理解的......

为了清楚起见,我会用图片解释我的情况。

enter image description here

这就是Window在" Normal"标签...

enter image description here

这就是Window看起来像一个荒谬的大文本......

enter image description here

现在,这就是我希望它在文字大得可笑时的样子

请参阅?

以下是示例代码:

# -*- 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()

请注意窗口不可调整大小。

如果您取消注释其中一个或两个&#34; Magic&#34;部分,您将看到窗口如何改变它的行为!

BUT

使用这两种方法时有两个缺点:

  • 如果您取消注释#self.set_resizable(True)窗口将再次成为可重新调整,我不希望它发生

  • #Box.set_resize_mode(Gtk.ResizeMode.QUEUE)似乎是&#34;完美&#34;解决方案,虽然它做了我想要的,它似乎已经&#34;折旧&#34;在最新版本的Gtk。

此外,在其他一些Window Managers&amp;主题,当你多次更改Label的字符串时,它会对Window的尺寸造成一些破坏。

你对此有什么建议吗?

我完全厌倦了这一点。我已经尝试了几个星期,没有结果:c

当Window可调整大小时,可能有一种模拟行为的方法,而不显示Resize Grips&amp;最大化按钮?

或者更新的方法是什么set_resize_mode(Gtk.ResizeMode.QUEUE)

PD:Label.set_max_width_chars()不是我正在搜索的内容

3 个答案:

答案 0 :(得分:2)

您可能想要了解Gtk 3.12中的帧时钟。这是一个很好的article。 用于排队调整大小的新方法是Gtk.Widget.queue_resize()

  

如果某些状态更改导致窗口小部件的大小发生变化,请调用gtk_widget_queue_resize(),它将请求布局阶段并将窗口小部件标记为需要重新布局。

我相信下面修改后的示例代码可以满足您的需求。诀窍在于包含子框以包围Gtk.LabelGtk.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()

答案 1 :(得分:2)

经过数小时的研究和实验,我找到了另一种完成这项任务的好方法。在我看来,这是最好的方法,除非它可能有点限制,但它允许你做更多的第一种方法和更少的代码。

这就是我所做的:

  • 从1°方法,我删除了“hackish”代码
  • 然后,我添加了一个“Mini-Box”对象,它是一个Gtk.ButtonBox(一种特殊的盒子......)并将其设置为“Homogeneous”
  • 之后,我从“Box”中删除了“Button”对象并添加了“Label”和&amp; “按钮”对象到“迷你盒子”
  • 更不用说我必须将“Mini-Box”添加到“Box”中......

完成!

以下是示例代码:

#!/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()

不会发布新的屏幕截图,因为结果与上面相同...

答案 2 :(得分:0)

嗯,经过一番思考后,我发现了一个&#34; hackish&#34;实现我想要的方式。

我会尝试用文字解释它,之后我会发布&#34; Final&#34;代码,但我确信它可以被优化,或者至少是我希望的那样:)

我所做的是采用两种代码(雅克·高丁的原始和修改版本),分析它们并创建一个不那么复杂的版本。

然后我意识到Jacques Gaudin的修改使得Window set_size_request依赖于开发者,因为它需要宽度和高度。

作为&#34;解决方法&#34;我决定做以下事情:

  • 清理代码
  • 让Window&#34;出现&#34;没有限制,所以它可以计算出正确显示所需的确切宽度和高度,并且可以隐藏窗口以避免用户按下&#34;随机按钮&#34;太早了。
  • 一旦Window隐藏了自己,请向它请求确切的值(宽度和高度)
  • 收集这些值后,当Window仍然隐藏时,重新声明MainWindow对象,但这次将其参数从(None, None)更改为先前收集的值:(Width, Height)
  • 接下来,Window需要通过更改其参数来重新计算一些内部值
  • 最后,一旦Window完成了重新计算的值,它就会再次显示自己,但这次显示所需的宽度和宽度。正确显示的高度即使由于某种原因标签增长,窗口也将保持相同的大小。

我知道这不是最好的&#34;回答,但至少它有效。

不幸的是,还有一些问题:

  • 我们怎样才能&#34;居中&#34;标签?
  • 如果在慢速机器中使用此方法,隐藏时窗口可能会变慢,如果用户按下&#34;随机化&#34;会导致某种错误/故障。按钮yoo早?
  • 动态文本翻译怎么样?他们甚至可以在不需要重新启动的情况下使用#34;窗户? (嗯,这不会是一个大问题,但仍然好奇想想......)
  • 有没有更好的方法来实现这个目标?(最重要的问题:c)

以下是代码:

#!/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

这是&#34;之前&#34;按下按钮......

enter image description here

这是&#34;之后&#34;按下按钮......