2016-10-12 21 views
0

私は数日間このことに固執してきました。私は決してPerlの専門家ではありません。Wxwidgets/Wx Perlグリッドサイジングの問題

私はWxPerlを使ってGUIアプリケーションを書いています。ノイズを減らすために、私は問題を抱えているアプリの一部を再作成しました。私はFormBuilderでレイアウトを設計し、その結果のXRCファイルを使用しました。 XRCデータは以下に含まれ、noname.xrcというファイルに保存されます。

GUIには2つのグリッド(左右)があり、中央に2つのボタンがあります。テストのために、メインフレームの上部に「行を追加」ボタンがあり、これは左のグリッドに行を追加します。残りのスペースを埋めるために左のグリッドの最後の列を調整するEVT_SIZE関数を作成し、同様の方法で右のグリッドを変更して、同じ比率に保ちます。

問題:

1)は、メインフレームウィンドウのサイズを調整し、その後、追加ボタンを20回クリックしてください。どのようにしてグリッドが急に拡大し、フレームの下部全体をどのように食べるかに注目してください。追加ボタンを数回クリックすると、底を食べ続けます...底部を食べないように高さを調整するように見えません。多分、私が紛失している明らかなフォーム設定がありますか? wxGridBagSizerからgrowablecolsフラグを削除しても、これが起こらないようにします。

2)おそらく比例したサイズに関連する迷惑な視覚的な問題。基本的に、グリッドの各辺(5x2)には10の境界詰めがあります。設定する前に幅から11を引いた値ですが、理想的には10にする必要があります。ただし、10に設定すると、最後の列が永久に成長し続ける...

3)メインフレームの右上隅にある「最大化」ボタンをクリックしてからもう一度クリックすると(「リストアダウン」と呼ばれます)、元に戻ります前のサイズに戻って、左のグリッドがEVT_SIZEイベントをトリガしないサイズを変更していないので、右のグリッドが決して調整されないことがわかります...これを修正する方法をブレーンストーミングしました。サイズイベントは、右のグリッドの位置を確認し、それがメインフレームの幅を超えているかどうかを判断できますか?これを適切なサイズにする簡単な方法はありますか?

理想的には、特定のグリッド列の最小サイズを設定したいが、メインウィンドウのサイズが変更されるとすべての列が大きくなるようにしたい。しかし、それはおそらくこの時点でパイプ夢です。

#!/usr/bin/perl 

package wxToplevelFrame; 
use strict; 
use warnings; 
use Wx qw(:everything); 
use Wx::Grid; 
use Wx::XRC; 
use base 'Wx::Frame'; 
use Data::Dumper; 
use diagnostics; 

# import event registration function 
use Wx::Event qw(:everything); 

use base qw(Wx::Panel Class::Accessor::Fast); 
__PACKAGE__->mk_ro_accessors(qw(xrc)); 

$| = 1; 

### GUI CODE BEGINS ### 

# create specialized constructor for new subclass 
sub new { 
    my $class = shift; 
    my $self = $class->SUPER::new(); 

    $self->initialize();  
    return $self; 
} 


sub initialize { 
    my ($self) = @_; 

    my $xrc_path = 'noname.xrc'; 

    Wx::InitAllImageHandlers(); 

    $self->{ xrc } = Wx::XmlResource->new(); 
    $self->xrc->InitAllHandlers(); 
    $self->xrc->Load($xrc_path); 
    $self->xrc->LoadFrame($self, undef, 'MyFrame1',); 

    # main frame close 
    EVT_CLOSE($self, 
     sub { 
      my ($self) = @_; 
      $self->Destroy(); 
     } 
    ); 


    # LEFT GRID 
    my $grid_left = $self->{ grid_left } = $self->FindWindow('m_grid4'); 
    $grid_left->CreateGrid(0, 3); 

    $grid_left->SetColLabelSize(25); # label height 
    $grid_left->SetRowLabelSize(25); # row width (far left, the numbers column basically) 

    $grid_left->SetColLabelValue(0, 'col_1'); 
    $grid_left->SetColLabelValue(1, 'col_2'); 
    $grid_left->SetColLabelValue(2, 'col_3'); 

    $grid_left->EnableDragColSize(0); 
    $grid_left->EnableDragRowSize(0); 
    $grid_left->EnableEditing(0); 

    $grid_left->SetDefaultRowSize(20); 

    $grid_left->SetColSize(0, 190); # col 1 
    $grid_left->SetColSize(1, 50); # col 2 
    $grid_left->SetColSize(2, 179); # col 3 


    # RIGHT GRID 
    my $grid_right = $self->{ grid_right } = $self->FindWindow('m_grid5'); 

    $grid_right->CreateGrid(0, 3); 

    $grid_right->SetColLabelSize(25); # label height 
    $grid_right->SetRowLabelSize(25); # row width (far left, the numbers column basically) 

    $grid_right->SetColLabelValue(0, 'col_'); 
    $grid_right->SetColLabelValue(1, 'col_2'); 
    $grid_right->SetColLabelValue(2, 'col_3'); 

    $grid_right->EnableDragColSize(0); 
    $grid_right->EnableDragRowSize(0); 
    $grid_right->EnableEditing(0); 

    $grid_right->SetDefaultRowSize(20); 

    $grid_right->SetColSize(0, 190); # col 1 
    $grid_right->SetColSize(1, 50); # col 2 
    $grid_right->SetColSize(2, 179); # col 3 

    #EVT_SIZE($grid_left, \&on_size); # adjust grid when size changes 
    #EVT_SIZE($grid_right, \&on_size); # adjust grid when size changes 

    my $on_size = \&on_size; 
    EVT_SIZE($grid_left, callback($on_size, $self, $grid_left)); 


    my $button = $self->{ button } = $self->FindWindow('m_button3'); 

    EVT_BUTTON(
     $button, 
     $button->GetId(), 
     callback(my $button_sub = \&add_row, $self, $button), 
    ); 

    my $gui_actions_text_ctrl = $self->FindWindow('m_textCtrl1'); 
    my $gui_log = Wx::LogTextCtrl->new($gui_actions_text_ctrl); 
    $self->{ gui_log_text_ctrl } = Wx::Log::SetActiveTarget($gui_log); 

    $self->SetStatusBarPane(-1); 
    return; 
} 

sub callback { 
    my $coderef = shift; 
    my @args = @_; 

    #print "what is args\n"; 
    #print Dumper \@args; 

    sub { $coderef->(@args) } 

    # callback function. when we want to pass addition args to a method call, such as an event (EVT_*), we can use this 
    # example: 
    # my $on_size_test = \&on_size_test; 
    # EVT_SIZE($grid_left, callback($on_size, $grid_left, $self)); 
} 

sub on_close { 
    my ($self) = @_; 
    $self->Destroy(); 
} 

sub on_size { 
    my ($self, $grid) = @_; 
    print "in on_size sub\n"; 

    # get the number of columns and the initial width which includes the far left number column (gutter column, with row indicators 1, 2, 3 ...) 
    my $num_cols = $grid->GetNumberCols(); 
    my $width  = $grid->GetRowLabelSize(); 
    my $gutter_col = $width; 

    print "num_cols: $num_cols\n"; 
    print "initial width: $width\n"; 

    my $col_0; 
    my $col_1; 
    my $col_2; 

    # iterate over each column, get size and add it to our width 
    for (my $col = 0; $col < $num_cols; $col++) { 

     # conditionals of no importance currently, but used during testing 
     if ($col == 0) { 
      $col_0 = $grid->GetColSize($col); 
      print "col: $col, width col_0: $col_0\n"; 

     } elsif ($col == 1) { 
      $col_1 = $grid->GetColSize($col); 
      print "col: $col, width col_1: $col_1\n"; 

     } elsif ($col == 2) { 
      $col_2 = $grid->GetColSize($col); 
      print "col: $col, width col_2: $col_2\n"; 
     } 
     $width += $grid->GetColSize($col); 
    } 

    print "width after iterating over each column: $width\n"; 

    # get sizer that grid is contained in 
    # get width of sizer and subtract it from the total width 
    # the difference will be the size we set for our last column 
    if ($num_cols > 0) { 

     my $static_box_sizer = $grid->GetContainingSizer(); 
     my $sizer   = $static_box_sizer->GetSize(); 
     my $sizer_width  = $sizer->GetWidth(); 

     print "sizer_width: $sizer_width\n"; 
     print "we are setting width for the last column. sizer_width: $sizer_width minus the total width: $width (gutter_col: $gutter_col, col_0, col_1, col_2)\n"; 

     my $width_diff = $sizer_width - $width + $col_2 - 11; # ideally this should be 10 for padding (5x2) on each side of sizer 
                   # but setting it at 10 causes the col to keep expanding... 

     print "width_diff result of above calc: $width_diff\n"; 

     $grid->SetColSize($num_cols - 1, $width_diff); # last column 

     # adjust grid right to reflect same proportions 
     $self->{ grid_right }->SetColSize($num_cols - 1, $width_diff); # last column   
    } 

    return; 
} 

sub add_row { 
    my ($self, $button) = @_; 

    $self->{ grid_left }->AppendRows(1); 

    my $col = 0; 
    foreach my $value ('testing', 100, 'Sat Aug 20 20:52:20 2016') { 
     my $row;  
     if ($col == 3) { 
      $self->{ grid_left }->AppendRows(1); 
      $row = $self->{ grid_left }->GetNumberRows() - 1; # minus one from total rows 
      print "col == 2\n"; 
      print "reset\n"; 
      print "what is row: $row\n"; 
      $col = 0; 
     } else { 
      $row = $self->{ grid_left }->GetNumberRows() - 1; 
     } 
     print "value: $value\n"; 

     $self->{ grid_left }->SetCellValue(
      $row, 
      $col, 
      $value, 
     ); 

     if ($col == 1) { 
      $self->{ grid_left }->SetCellAlignment(
       $row, 
       $col, 
       wxALIGN_RIGHT, 
       wxALIGN_CENTRE, 
      ); 

     } elsif ($col == 2) { 
      $self->{ grid_left }->SetCellAlignment(
       $row, 
       $col, 
       wxALIGN_CENTRE, 
       wxALIGN_CENTRE, 
      ); 
     } 
     $col++; 

    } 
} 
### GUI CODE ENDS ### 

# END: wxToplevelFrame package 


# create an app object 
package MyApp; 
use strict; 
use warnings; 
use base 'Wx::App'; 

# OnInit is called automatically when an app object is first constructed 
sub OnInit { 
    my $self = shift; 
    my $toplevel_frame = wxToplevelFrame->new(); 
    $self->SetTopWindow($toplevel_frame); 
    $toplevel_frame->Show(1); 
} 
# END: MyApp package 


package main; 
use strict; 
use warnings; 
use Data::Dumper; 

$| = 1; 

my $app = MyApp->new(); # instantiate our app first 
$app->MainLoop(); 

exit; 

XRCファイル:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> 
<resource xmlns="http://www.wxwindows.org/wxxrc" version="2.3.0.1"> 
    <object class="wxFrame" name="MyFrame1"> 
     <style>wxCAPTION|wxCLOSE_BOX|wxMAXIMIZE_BOX|wxMINIMIZE_BOX|wxRESIZE_BORDER|wxSYSTEM_MENU|wxFULL_REPAINT_ON_RESIZE|wxTAB_TRAVERSAL</style> 
     <size>998,700</size> 
     <title>Grid Issues</title> 
     <centered>1</centered> 
     <aui_managed>0</aui_managed> 
     <object class="wxPanel" name="m_panel6"> 
      <style>wxTAB_TRAVERSAL</style> 
      <object class="wxBoxSizer"> 
       <orient>wxVERTICAL</orient> 
       <object class="sizeritem"> 
        <option>1</option> 
        <flag>wxALL|wxEXPAND</flag> 
        <border>5</border> 
        <object class="wxFlexGridSizer"> 
         <rows>0</rows> 
         <cols>6</cols> 
         <vgap>0</vgap> 
         <hgap>0</hgap> 
         <growablecols></growablecols> 
         <growablerows></growablerows> 
         <object class="sizeritem"> 
          <option>0</option> 
          <flag>wxALL</flag> 
          <border>5</border> 
          <object class="wxButton" name="m_button3"> 
           <label>add row</label> 
           <default>0</default> 
          </object> 
         </object> 
        </object> 
       </object> 
       <object class="sizeritem"> 
        <option>3</option> 
        <flag>wxEXPAND|wxLEFT|wxRIGHT</flag> 
        <border>5</border> 
        <object class="wxGridBagSizer"> 
         <vgap>0</vgap> 
         <hgap>0</hgap> 
         <growablecols>0,2</growablecols> 
         <growablerows>0</growablerows> 
         <object class="sizeritem"> 
          <cellpos>0,0</cellpos> 
          <cellspan>1,1</cellspan> 
          <flag>wxALL|wxEXPAND</flag> 
          <border>5</border> 
          <object class="wxStaticBoxSizer"> 
           <orient>wxHORIZONTAL</orient> 
           <label>left</label> 
           <object class="sizeritem"> 
            <option>1</option> 
            <flag>wxALL|wxEXPAND</flag> 
            <border>5</border> 
            <object class="wxGrid" name="m_grid4" /> 
           </object> 
          </object> 
         </object> 
         <object class="sizeritem"> 
          <cellpos>0,1</cellpos> 
          <cellspan>1,1</cellspan> 
          <flag>wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL</flag> 
          <border>5</border> 
          <object class="wxBoxSizer"> 
           <orient>wxVERTICAL</orient> 
           <object class="sizeritem"> 
            <option>0</option> 
            <flag>wxALL</flag> 
            <border>5</border> 
            <object class="wxButton" name="m_button4"> 
             <style>wxBU_EXACTFIT</style> 
             <label>&gt;</label> 
             <default>0</default> 
            </object> 
           </object> 
           <object class="sizeritem"> 
            <option>0</option> 
            <flag>wxALL</flag> 
            <border>5</border> 
            <object class="wxButton" name="m_button5"> 
             <style>wxBU_EXACTFIT</style> 
             <label>&lt;</label> 
             <default>0</default> 
            </object> 
           </object> 
          </object> 
         </object> 
         <object class="sizeritem"> 
          <cellpos>0,2</cellpos> 
          <cellspan>1,1</cellspan> 
          <flag>wxALL|wxEXPAND</flag> 
          <border>5</border> 
          <object class="wxStaticBoxSizer"> 
           <orient>wxHORIZONTAL</orient> 
           <label>right</label> 
           <object class="sizeritem"> 
            <option>1</option> 
            <flag>wxALL|wxEXPAND</flag> 
            <border>5</border> 
            <object class="wxGrid" name="m_grid5" /> 
           </object> 
          </object> 
         </object> 
        </object> 
       </object> 
       <object class="sizeritem"> 
        <option>2</option> 
        <flag>wxEXPAND | wxALL</flag> 
        <border>5</border> 
        <object class="wxNotebook" name="m_notebook2"> 
         <object class="notebookpage"> 
          <label>a page</label> 
          <selected>0</selected> 
          <object class="wxPanel" name="m_panel2"> 
           <style>wxTAB_TRAVERSAL</style> 
           <object class="wxBoxSizer"> 
            <orient>wxHORIZONTAL</orient> 
            <object class="sizeritem"> 
             <option>1</option> 
             <flag>wxALL|wxEXPAND</flag> 
             <border>5</border> 
             <object class="wxTextCtrl" name="m_textCtrl1"> 
              <value></value> 
             </object> 
            </object> 
           </object> 
          </object> 
         </object> 
        </object> 
       </object> 
      </object> 
     </object> 
     <object class="wxStatusBar" name="m_statusBar1"> 
      <style>wxST_SIZEGRIP</style> 
      <fields>2</fields> 
     </object> 
    </object> 
</resource> 

大歓迎任意のヘルプnoname.xrc、あまりにも多くのコードはここにあります

-Jdun

答えて

1

おかげで、それをすべて慎重に読んでください私に疑いの余地があるのは、on_sizeハンドラのイベントで$event->Skip()に電話しないということです。 EVT_SIZEハンドラは、ほとんど常にSkip()を呼び出して、サイズイベントのデフォルト処理を実行できるようにする必要があります。問題のすべてを説明できないかもしれませんが、少なくとも一部について説明していないと驚きます。

+0

返信いただきありがとうございます。私はこれを再訪し、あなたの提案を試してみてください。私は移動しなければならなかったし、サイズ変更を防ぐためにフォームをロックしてサイジングの問題を回避し、それがプレイ中に垂直スクロールバーを占めた。 – Jdun

関連する問題