wxGrid:如何在小网格周围安装外窗口? [英] wxGrid: How to fit the outer window around a small grid?

查看:36
本文介绍了wxGrid:如何在小网格周围安装外窗口?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

总结:我不知道如何设置主窗口尺寸,以便在不更改列的默认宽度的情况下在 wxGrid 周围不使用滚动条.

Summary: I do not know how to set the main window dimensions so that no scroll bars are used around the wxGrid without changing the default widths of the columns.

我想编写一个简单的应用程序,用户可以在其中看到有限数量的数字,她可以更正其中的一些数字并保存新内容.应用程序应该是一种简约的.行和单元格的数量足够小,可以在不需要滚动条的情况下放入一个窗口.这是一个简化的代码:

I want to write a simple application where user can see a limited number of numbers, and she can make correction of some of them and save the new content. The application should be a kind of minimalistic. The number of rows and cells is small enough to fit in a window without the need for scroll bars. Here is a simplified code:

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 包含唯一的控件——网格:

There will be some button below the grid. For now, the only sizer contains the only controll -- the grid:

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

代码被放入我的AppFrame 类的构造函数中.最后,我调用以下内容:

The code is placed into the constructor of my AppFrame class. Finally, I call the following:

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

它几乎完全符合我的需要,但有些列有更长的标签,并且 Fit 改变了列的宽度.视觉上不是很好.我应该调用什么来代替 Fit 以获得相同的效果但不改变统一的列宽?

It does almost exactly what I need, but some columns have longer labels and the Fit changes the widths of the columns. It is not nice visually. What should I call instead of Fit to get the same effect but without changing the uniform column widths?

更新: 其实,我之前没有注意到,在我的代码中也调用了 grid->Fit(); (现在添加到上面的例子中).删除它后,网格不会在内部设置其尺寸并且窗口非常小(即使左上角的窗口在高度上也不是完全可见,宽度上也没有完全可见.然后我还添加了 SetColSize 对于每一列(到我设置列格式的同一个地方):

Update: Actually, I did not noticed earlier, that also grid->Fit(); was called in my code (added now to the above example). After removing it, the grid does not set internally its dimensions and the window is extremely small (even the upper left corner window is not fully visible in height and ony a bit more that that on width. Then I have added also SetColSize for each column (to the same place where I set the format for the columns):

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

这没有帮助,而且窗口比想要的要小.因此,问题可能应该改写:填充的网格如何捕获自己的尺寸以报告给外部包装器?

This did not help and the window is smaller than wanted. So, question should probably be reworded: How the filled grid can capture its own dimensions to be reported to the outer wrapper?

更新 2:它仍然不起作用.构造函数的完整代码.(我知道,在椅子和键盘之间的某个地方...... :) 我个人认为我的代码有点脏(至少对于魔术数字)——可能稍后清理:

Update 2: It still does not work. The full code of the constructor. (I know, somewhere between the chair and the keyboard... :) I personally consider i a bit dirty code (at least for the magic numbers) -- possibly cleaned up later:

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

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

Thanks for your time and experience, Petr

推荐答案

这是一个完整的工作程序:

Here is a complete working program:

#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()(但您不喜欢这样),或者只是统一增加列宽.

Notice that for me "September" doesn't fit into the default column width, either call AutoSizeColumns() (but you don't like this) or just increase the column width uniformly.

这篇关于wxGrid:如何在小网格周围安装外窗口?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆