wxAuiToolBar的overflow cannot work on GTK 解决方法

wxAuiToolBar‘s overflow function cannot work as expected, when as pane in wxAuiManager, on GTK.

当增加一个AuiToolBar到一个auimanager之后,如果想用它的overflow feature,在gtk平台,无法工作。 WHY?

1) 首先查看wxAuiToolBar的OnSize函数做了些什么事情:

void wxAuiToolBar:: OnSize(wxSizeEvent & WXUNUSED (evt))
{
     int x , y;
    GetClientSize(&x , &y);

    if (x > y)
         SetOrientation(wxHORIZONTAL );
    else
        SetOrientation(wxVERTICAL );

    if (((x >= y) && m_absolute_min_size .x > x) ||
        (( y > x ) && m_absolute_min_size.y > y))
    {
        // hide all flexible items
        size_t i , count;
        for (i = 0, count = m_items.GetCount (); i < count; ++i )
        {
            wxAuiToolBarItem& item = m_items. Item(i );
            if (item .sizer_item && item.proportion > 0 && item .sizer_item-> IsShown())
            {
                item.sizer_item ->Show( false);
                item.sizer_item ->SetProportion(0);
            }
        }
    }
    else
    {
        // show all flexible items
        size_t i , count;
        for (i = 0, count = m_items.GetCount (); i < count; ++i )
        {
            wxAuiToolBarItem& item = m_items. Item(i );
            if (item .sizer_item && item.proportion > 0 && !item .sizer_item-> IsShown())
            {
                item.sizer_item ->Show( true);
                item.sizer_item ->SetProportion( item.proportion );
             }
        }
     } 

     m_sizer->SetDimension (0, 0, x, y);

    Refresh(false );
    Update();
 }

可以看到函数对一些tool button做了show/hide设置。
然后设置断点,跟踪每次size时, x/y计算出来的值是多少。发现它始终就没变过,不管如何resize那个toolbar

2) 不从ClientSize里面获取x/y值,从evt参数中拿值。看下上层代码是如何给它值。发现下面函数触发OnSize函数调用:

void wxAuiToolBar:: DoSetSize(int x,
                         int y ,
                         int width ,
                         int height ,
                         int sizeFlags )
{
     wxSize parent_size = GetParent()-> GetClientSize();
     if (x + width > parent_size.x )
        width = wxMax (0, parent_size. x - x );
     if (y + height > parent_size.y )
        height = wxMax (0, parent_size. y - y );

     wxWindow::DoSetSize (x, y, width , height, sizeFlags);
 }

跟踪发现width/height确实是更改过的值,但是在wxWindow::DoSetSize函数中,但是gtk版本的DoSetSize函数(src/gtk/window.cpp: 2712行),对width/height进行了进一步的处理。在函数最后处理size事件

2829     if (!m_nativeSizeEvent)
2830     {
2831         wxSizeEvent event( wxSize(m_width,m_height), GetId() );
2832         event.SetEventObject( this );
2833         GetEventHandler()->ProcessEvent( event );
2834     }

跟踪发现m_width/m_height,确实在函数内部以下代码段中更改了。

2744     int minWidth  = GetMinWidth(),
2745         minHeight = GetMinHeight(),
2746         maxWidth  = GetMaxWidth(),
2747         maxHeight = GetMaxHeight();
2748
2749     if ((minWidth  != -1) && (m_width  < minWidth )) m_width  = minWidth;
2750     if ((minHeight != -1) && (m_height < minHeight)) m_height = minHeight;
2751     if ((maxWidth  != -1) && (m_width  > maxWidth )) m_width  = maxWidth;
2752     if ((maxHeight != -1) && (m_height > maxHeight)) m_height = maxHeight;

GetMinWidth函数调用GetMinSize函数获取widht。跟踪发现这个minsize失踪是toolbar最初显示出来的size。我们并没有设置它的minsize啊?是谁在其间调用了SetMinSize函数设置其值了?

3) GDB断点跟踪发现,在auimanager的Update函数中调用了Sizer的SetItemMinSize函数,进而调用了toolbar的SetMinSize函数:

1658 void wxAuiManager::LayoutAddPane(wxSizer* cont,
1659                                  wxAuiDockInfo& dock,
1660                                  wxAuiPaneInfo& pane,
1661                                  wxAuiDockUIPartArray& uiparts,
1662                                  bool spacer_only)
...
1779     // determine if the pane should have a minimum size; if the pane is
1780     // non-resizable (fixed) then we must set a minimum size. Alternatively,
1781     // if the pane.min_size is set, we must use that value as well
1782
1783     wxSize min_size = pane.min_size;
1784     if (pane.IsFixed())
1785     {
1786         if (min_size == wxDefaultSize)
1787         {
1788             min_size = pane.best_size;
1789             pane_proportion = 0;
1790         }
1791     }
1792
1793     if (min_size != wxDefaultSize)
1794     {
1795         vert_pane_sizer->SetItemMinSize(
1796                         vert_pane_sizer->GetChildren().GetCount()-1,
1797                         min_size.x, min_size.y);
1798     }

我们的toolbar是一个fixed的pane,开始时并没有设置它的min size,所以1788行将会设置为best size,而best size将会是初始化时的size。这样1795行将会被调用到,而且是以best size的值来调用。

4) 找到根源之后,如何修改?
最简单的方式是在auimanager.AddPane调用增加toolbar时,设置它的minsize为一个tool button的size。这个size可以从toolbar提供的接口获取到。

wxAuiToolBar的overflow cannot work on GTK 解决方法

时间: 2024-07-30 09:40:23

wxAuiToolBar的overflow cannot work on GTK 解决方法的相关文章

css ie7中overflow:hidden失效问题及解决方法

css兼容ie7: 做页面的时候用负边距居中的时候在IE7下面,父节点中的overflow:hiden失效的问题,查阅了一些资料,总结一下解决方法. 问题原因: 当父元素的直接子元素或者下级子元素的样式拥有position:relative属性时,父元素的overflow:hidden属性就会失效. 解决方法: 我们在IE7内发现子元素会超出父元素设定的高度,即使父元素设置了overflow:hidden. 解决这个bug很简单,在父元素中使用position:relative;即可解决该bug

v9更新栏目缓存提示PHP has encountered a Stack overflow解决方法

原因: 客户在把一些栏目删除或者新增栏目时没更新栏目缓存导致v9_category表里有原来的垃圾信息,多余的表. 解决方法:通过phpmyadmin找到栏目表出错的条目,修改错误信息. 具体步骤: 1.首先这个问题是出在数据库表上,所以登录空间的phpmyadmin去管理数据库表 2.执行SQL语句:SELECT * FROM `v9_category` WHERE catid=parentid(注意,v9_是表前缀,记得修改成自己的表前缀) 3.正常情况下这个搜索是查询不到记录的,如果查询到

关于微信二次分享,描述变链接的解决方法(一)----文档说明

http://www.cnblogs.com/joshua317/p/4761948.html 前言: 最近工作中遇到了使用微信二次分享的时候,标题被截短,描述也变成了链接,图片也没有,运营人员半夜还在嚷嚷,无奈只好硬着头皮去百度,去google,但是悲催的是没有详细的解决方法,最终只能自己去研究,还好最终搞出来了,决定分享一下,帮助需要的人.博文,分两篇,第一篇主要是微信的官方文档说明,第二篇主要是代码部分: 一.微信JS-SDK说明文档 1.概述 微信JS-SDK是微信公众平台面向网页开发者

【spring boot+mybatis】注解使用方式(无xml配置)设置自动驼峰明明转换(),IDEA中xxDao报错could not autowire的解决方法

最近使用spring boot+mybatis,使用IntelliJ IDEA开发,记录一些问题的解决方法. 1.在使用@Mapper注解方式代替XXmapper.xml配置文件,使用@Select等注解配置sql语句的情况下,如何配置数据库字段名到JavaBean实体类属性命的自动驼峰命名转换? 使用spring boot后,越来越喜欢用注解方式进行配置,代替xml配置文件方式.mybatis中也可以完全使用注解,避免使用xml方式配置mapper.(参考  springboot(六):如何优

css的兼容性问题和解决方法

1. 默认的内外边距不同 问题: 各个浏览器默认的内外边距不同 解决: *{margin:0;padding:0;} 2. 水平居中的问题 问题: 设置 text-align: center ie6-7文本居中,嵌套的块元素也会居中 ff /opera /safari /ie8文本会居中,嵌套块不会居中 解决: 块元素设置 1.margin-left:auto;margin-right:auto 2.margin:0 auto; 3. <div align=”center”>div> 3

eclipse一直卡住,出现 “android sdk content loader 0%” 卡住的错误分析及解决方法

分析:这种问题之前没有遇到过,也不知道什么原因,直接去网上查询,打开www.stackoverflow.com,输入要查询问题的关键词,我们输入 “android sdk content loader 0%”,查询结果如下:      我们找到投票数最多的这个回答: 以下是我所找到的有效的解决方法:1.首先确保 eclipse 已经关闭.如果 eclipse 还处于打开状态,请从任务管理器的进程列表中杀死 eclipse .2.在 Windows 上可以通过 %USERPROFILE%/,在 L

使用sublime text 2 版本至今我所遇到的问题及解决方法

1.汉化:下载汉化包 .打开程序Preference下的浏览包文件夹.将解压的程序包粘贴进包文件夹2.破解:标题栏上面有带(unregistered)表示还没有注册: 打开HELP→Enter license粘贴如下代码 ----- BEGIN LICENSE ----- Andrew Weber Single User License EA7E-855605 813A03DD 5E4AD9E6 6C0EEB94 BC99798F 942194A6 02396E98 E62C9979 4BB97

用bootstrap兼容ie各大浏览器的解决方法

以bootstrap为框架常常会出现不兼容ie各大浏览器的问题,用以下代码基本可以解决,一般在<head></head>加入以下代码后,网页可能还一些比较不美观,再写一点css hack就可以了,如果加入以下代码网页还是特别乱,请检查一下你的css和js的文件顺序,有加载顺序的... <!--[if lte IE 6]> <link rel="stylesheet" type="text/css" href="st

IE6 Bug解决方法HACK汇总

1.终极方法:条件注释<!--[if lte IE 6]> 这段文字仅显示在 IE6及IE6以下版本. <![endif]--><!--[if gte IE 6]> 这段文字仅显示在 IE6及IE6以上版本. <![endif]--><!--[if gt IE 6]> 这段文字仅显示在 IE6以上版本(不包含IE6). <![endif]--><!--[if IE 5.5]> 这段文字仅显示在 IE5.5. <![e