0

概要:列のデフォルト幅を変更せずに wxGrid の周りにスクロール バーが使用されないように、メイン ウィンドウのサイズを設定する方法がわかりません。

ユーザーが限られた数の数字を表示できる単純なアプリケーションを作成し、それらの一部を修正して新しいコンテンツを保存できるようにしたいと考えています。アプリケーションは一種の最小限のものでなければなりません。行とセルの数は、スクロール バーを必要とせずにウィンドウに収まるほど小さいです。簡略化されたコードは次のとおりです。

wxGrid *grid = new wxGrid(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);
grid->CreateGrid(21, 12);

// Setting the column labels and filling the grid with some numbers.

grid->Fit();

グリッドの下にいくつかのボタンがあります。今のところ、唯一のサイザーには、唯一のコントロール (グリッド) が含まれています。

wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
topSizer->Add(grid, 1, wxEXPAND);
SetSizer(topSizer);

コードはAppFrameクラスのコンストラクターに配置されます。最後に、次のように呼び出します。

topSizer->Fit(this);
topSizer->SetSizeHints(this);

それは私が必要とすることをほぼ正確に行いますが、一部の列には長いラベルがありFit、列の幅が変更されます。視覚的に良くありません。Fit同じ効果を得る代わりに、均一な列幅を変更せずに何を呼び出す必要がありますか?

更新:実際、以前は気付かなかったのですgrid->Fit();が、コードでも呼び出されていました (上記の例に追加されました)。それを削除した後、グリッドは内部でその寸法を設定せず、ウィンドウは非常に小さくなります (左上隅のウィンドウでさえ、高さが完全に表示されず、幅が少し大きくなります。次にSetColSize、各列にも追加しました (列のフォーマットを設定したのと同じ場所に移動します):

for (int i = 0; i < 12; ++i)
{
    grid->SetColSize(i, WXGRID_DEFAULT_COL_WIDTH);
    grid->SetColFormatFloat(i, -1, 3);
}

これは役に立ちませんでした。ウィンドウは必要以上に小さくなっています。したがって、質問はおそらく言い換える必要があります:塗りつぶされたグリッドは、外部ラッパーに報告される独自のディメンションをどのようにキャプチャできますか?

更新 2:まだ機能しません。コンストラクターの完全なコード。(私は知っています、椅子とキーボードの間のどこか... :)個人的には、少し汚いコードだと思います(少なくともマジックナンバーについて)-おそらく後でクリーンアップされます:

AppFrame::AppFrame() :
    wxFrame(NULL, wxID_ANY, "Month rates of Euro")
{
    InitDefaultRates();

    wxGrid *grid = new wxGrid(this, wxID_ANY, wxDefaultPosition, wxDefaultSize);

    // Fixed grid for 12 months (columns) and the years 2000 to 2020 (rows).
    //
    grid->CreateGrid(21, 12);

    grid->BeginBatch();

    // Set the column labes (in Czech -- to lazy to translate).
    //
    grid->SetColLabelValue(0,  "leden");
    grid->SetColLabelValue(1,  "únor");
    grid->SetColLabelValue(2,  "březen");
    grid->SetColLabelValue(3,  "duben");
    grid->SetColLabelValue(4,  "květen");
    grid->SetColLabelValue(5,  "červen");
    grid->SetColLabelValue(6,  "červenec");
    grid->SetColLabelValue(7,  "srpen");
    grid->SetColLabelValue(8,  "září");
    grid->SetColLabelValue(9,  "říjen");
    grid->SetColLabelValue(10, "listopad");
    grid->SetColLabelValue(11, "prosinec");

    // Float with 3 decimal places for each of the columns.
    //
    for (int i = 0; i < 12; ++i)
    {
        grid->SetColFormatFloat(i, -1, 3);
    }

    // Filling with the default values calculated from 
    // http://www.ecb.europa.eu/stats/eurofxref/eurofxref-hist.zip.
    // Index zero is for the year 2000.
    //
    for (int year = 0; year < 21; ++year)
    {
        ostringstream oss;
        oss << 2000 + year;
        grid->SetRowLabelValue(year, oss.str().c_str());

        for (int month = 0; month < 12; ++month)
        {
            double default_value = default_rates[year][month];
            double value = default_value;

            oss.str("");
            oss << setprecision(3) << fixed << value;

            // Problem with decimal point separator. Replace the locale
            // comma by dot.
            //
            wxString s(oss.str().c_str());
            string::size_type pos = s.find_first_of('.');
            if (pos != string::npos)
                s[pos] = ',';

            grid->SetCellValue(year, month, s);

            if (value == 0.0)
                grid->SetCellTextColour(year, month, *wxLIGHT_GREY);
            else if (value == default_value)
                grid->SetCellTextColour(year, month, *wxBLUE);
        }
    }

    // Setting the initial size of the grid.
    //
    grid->SetInitialSize(grid->GetBestSize());

    // Vertical size will be the top one.
    //
    wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
    topSizer->Add(grid, 1, wxEXPAND);
    SetSizer(topSizer);

    // I do not understand this (could be a problem). From wxBook p. 196.
    //
    topSizer->Fit(this);
    topSizer->SetSizeHints(this);

    // Allow redraw.
    //
    grid->EndBatch();

    // Set cursor to the current month.
    //
    int year = wxDateTime::GetCurrentYear() - 2000;
    int month = wxDateTime::GetCurrentMonth();
    grid->GoToCell(year, month);
}

時間と経験をありがとう、Petr

4

1 に答える 1

2

完全な作業プログラムは次のとおりです。

#include "wx/app.h"
#include "wx/frame.h"
#include "wx/grid.h"
#include "wx/datetime.h"

class MyFrame : public wxFrame
{
public:
    MyFrame()
        : wxFrame(NULL, wxID_ANY, "Chronological data")
    {
        wxGrid *grid = new wxGrid(this, wxID_ANY);
        grid->CreateGrid(21, 12);

        for ( wxDateTime::Month m = wxDateTime::Jan; m < wxDateTime::Inv_Month; wxNextMonth(m) )
        {
            grid->SetColLabelValue(m, wxDateTime::GetMonthName(m));
            for ( int y = 0; y < 21; y++ )
            grid->SetCellValue(y, m, wxString::Format("%.2f", (float)rand() / RAND_MAX));
        }

        grid->InvalidateBestSize();
        SetClientSize(grid->GetBestSize());
    }
};

class MyApp : public wxApp
{
public:
    virtual bool OnInit()
    {
        (new MyFrame)->Show();
        return true;
    }
};

wxIMPLEMENT_APP(MyApp);

私にとって、「9月」はデフォルトの列幅に収まらないことに注意してください。呼び出すAutoSizeColumns()(ただし、これは好きではありません)か、単に列幅を均一に増やします。

于 2012-11-08T19:27:04.520 に答える