在 GTK 4.0 中获取小部件的计算大小

问题描述 投票:0回答:2

是否可以找出小部件的计算大小,例如,

GtkButton
,以及 GTK 4.0 下大小何时发生变化?我尝试了很多不同的方法,但似乎都不起作用。

看起来在 GTK 3.0 下可以使用

size-allocate
信号,但已被删除。我知道这种情况很少需要,但肯定有某种方法可以知道 a) 大小何时更改以及 b) 新分配的大小是多少。

gtk gtk4
2个回答
1
投票

size_allocate 现在是一个虚拟方法。它仅供小部件实现本身使用,以为其子项分配大小和位置。

要获取 size_allocate 之外的小部件的大小,您可以使用 get_allocation

如果您试图使另一个小部件的大小与按钮的大小同步,您应该使用 GtkSizeGroup 来代替。


0
投票

我发现了一个黑客解决方法,可能会引起想要这样做的人的兴趣。基本思想是利用

GtkDrawingArea
resize
信号。我们将制作几个如下所示的小部件:

 __________________________________
|               DA                 |
|----------------------------------|
| |                                |
|D| widget you actually care about |
|A|                                | 
| |                                |
`----------------------------------'

两个DA分别是零高度+“无限”宽度和“无限”宽度+零高度的绘图区域,这些区域用

GtkBox
es进行布局。我们必须安排您真正关心的小部件中的一些布局选项传递到框中,绕过绘图区域的“无限”大小。我还没有对此进行详尽的测试,但它似乎几乎满足了我的需求,因此您可能也会感兴趣。

这是完整的源代码——用 Haskell 拼写,但希望这个想法足够清晰,源代码可以为您提供进入您最喜欢的语言的 Gtk 绑定的文档所需的所有指针。

import Data.GI.Base.Attributes
import Data.GI.Base.Signals
import GI.GLib
import GI.Gtk

data SizeAllocationMonitor = SAM
    { samHorizontalArea :: DrawingArea
    , samVerticalArea :: DrawingArea
    , samHorizontalBox :: Box
    , samVerticalBox :: Box
    , samChild :: Widget
    }

newSizeAllocationMonitor :: Widget -> IO SizeAllocationMonitor
newSizeAllocationMonitor child = do
    ha <- new DrawingArea [#hexpand := True , #vexpand := False]
    va <- new DrawingArea [#hexpand := False, #vexpand := True ]
    hb <- new Box $ tail [undefined
        , #orientation := OrientationHorizontal
        , #hexpand :=> get child #hexpand
        , #widthRequest :=> get child #widthRequest
        ]
    vb <- new Box $ tail [undefined
        , #orientation := OrientationVertical
        , #vexpand :=> get child #vexpand
        , #heightRequest :=> get child #heightRequest
        ]

    #append vb ha
    #append vb hb
    #append hb va
    #append hb child

    return (SAM ha va hb vb child)

samOnResize :: SizeAllocationMonitor -> (Int32 -> Int32 -> IO ()) -> IO [SignalHandlerId]
samOnResize sam callback = do
    hid <- on (samHorizontalArea sam) #resize invokeCallback
    vid <- on (samVerticalArea   sam) #resize invokeCallback
    return [hid, vid]
    where
    invokeCallback _ _ = do
        w <- #getAllocatedWidth  (samChild sam)
        h <- #getAllocatedHeight (samChild sam)
        callback w h

samDisconnectHandler :: SizeAllocationMonitor -> [SignalHandlerId] -> IO ()
samDisconnectHandler sam [hid, vid] = do
    disconnectSignalHandler (samHorizontalArea sam) hid
    disconnectSignalHandler (samVerticalArea   sam) vid

samWidget :: SizeAllocationMonitor -> IO Widget
samWidget = toWidget . samVerticalBox
© www.soinside.com 2019 - 2024. All rights reserved.