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();

网格下方会有一些按钮。目前,唯一的 sizer 包含唯一的控件——网格:

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:它仍然不起作用。构造函数的完整代码。(我知道,在椅子和键盘之间的某个地方...... :) 我个人认为 ia 有点脏代码(至少对于幻数而言) - 可能稍后会清理:

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);
}

感谢您的时间和经验,彼得

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);

请注意,对我来说,“September”不适合默认列宽,要么调用AutoSizeColumns()(但你不喜欢这样),要么只是统一增加列宽。

于 2012-11-08T19:27:04.520 回答