是否可以找出小部件的计算大小,例如,
GtkButton
,以及 GTK 4.0 下大小何时发生变化?我尝试了很多不同的方法,但似乎都不起作用。
看起来在 GTK 3.0 下可以使用
size-allocate
信号,但已被删除。我知道这种情况很少需要,但肯定有某种方法可以知道 a) 大小何时更改以及 b) 新分配的大小是多少。
size_allocate 现在是一个虚拟方法。它仅供小部件实现本身使用,以为其子项分配大小和位置。
要获取 size_allocate 之外的小部件的大小,您可以使用 get_allocation。
如果您试图使另一个小部件的大小与按钮的大小同步,您应该使用 GtkSizeGroup 来代替。
我发现了一个黑客解决方法,可能会引起想要这样做的人的兴趣。基本思想是利用
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