【问题标题】:wxGrid destructor Triggers Breakpoint onwxGrid 析构函数触发断点
【发布时间】:2015-09-17 21:22:01
【问题描述】:

我是 wxWidgets 的新手,尽管在此之前我已经能够相当顺利地启动和运行应用程序。对于主窗口,我在 wxPanel 中使用了 wxGrid。在我关闭程序之前一切都运行良好。

提前感谢您的任何见解。

网格是从 wxPanel 派生的类的成员:

class FormDataView
        : public wxPanel
    {

public:
    FormDataView(wxWindow* parent);
    virtual ~FormDataView();

private:
        wxGrid* grid_;
    }

并在构造函数中创建。网格的数据来自另一个线程,所以我创建了一个自定义事件来实际写入数据。

wxDEFINE_EVENT(FORMDATAVIEW_UPDATE, wxThreadEvent);


FormDataView::FormDataView(wxWindow* parent)
        :   wxPanel(parent,wxID_ANY )
    {

    wxBoxSizer* mbox = new wxBoxSizer(wxVERTICAL);
    grid_ = new wxGrid(this, wxID_ANY );
    grid_->CreateGrid(0, 0);


    mbox->Add(grid_,wxSizerFlags(1).Expand());


    Bind(FORMDATAVIEW_UPDATE, &FormDataView::onDataUpdate, this);

    }


///
/// This function is called by a child thread when data is received.
///
void
FormDataView::onDataReceived(IFORMATTERBASE_PFONDATARECEIVED_ARGS)
    {
    newHeaders_ = headers;
    newData_ = data;

    wxThreadEvent* evt = new wxThreadEvent(FORMDATAVIEW_UPDATE);
    evt->SetString("Yo.");
    wxQueueEvent(this, evt);

    }


///
/// Called by the event loop. This function puts the data
/// into the grid.
///
void 
FormDataView::onDataUpdate(wxThreadEvent& evt)
    {
    FormatterStringList& headers = newHeaders_;
    FormatterStringList& data = newData_;

    if (grid_->GetNumberRows() <= 0)
        {

        wxGridCellAttr* attr = new wxGridCellAttr();
        attr->SetReadOnly(true);
        attr->SetAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
        for (size_t i = 0; i<headers.size(); ++i)
            {

            if (grid_->GetNumberCols() <= 0)
                grid_->InsertCols();
            else
                grid_->AppendCols();


            grid_->SetColLabelValue(i, headers[i].data());
            grid_->SetColAttr(i, attr);
            }
        }


    // suspend redrawing while we add data.
    grid_->BeginBatch();

    // insert a new row at the top of the table
    grid_->InsertRows(
        0, // position
        1, // number of rows to insert
        true); // update labels (not current used)


    for (size_t i = 0; i<headers.size(); ++i)
        {

        if (data.size() < i)
            {
            grid_->SetCellValue(0, i, "");
            }
        else
            {
            grid_->SetCellValue(0, i, data[i].data());
            }
        }

    // resume redrawing.
    grid_->EndBatch();
    }

一切运行良好,但是当我关闭时,我收到以下消息。我已经指出了断点所在的行。从我应该遵循的网格中清除数据是否有一些不足的顺序?

wxGrid::CellSpan
wxGrid::GetCellSize( int row, int col, int *num_rows, int *num_cols ) const
{
    wxGridCellAttr *attr = GetCellAttr(row, col);
    attr->GetSize( num_rows, num_cols );
    attr->DecRef();

>>>>>>>    if ( *num_rows == 1 && *num_cols == 1 )
        return CellSpan_None; // just a normal cell

    if ( *num_rows < 0 || *num_cols < 0 )
        return CellSpan_Inside; // covered by a multi-span cell

    // this cell spans multiple cells to its right/bottom
    return CellSpan_Main;
}

【问题讨论】:

  • 您显示的代码没有任何问题,但这只是意味着错误出现在您未显示的代码中,这使得即使不是不可能也很难找到它。至少看看为什么代码会崩溃,也许堆栈跟踪显示了一些提示......(同时检查它发生在哪个线程)。
  • 其实问题出在代码中;我今天早上想通了。而且我有点尴尬。修改后的代码。

标签: wxwidgets wxgrid


【解决方案1】:

问题在于我创建列属性的位置。我为每一列重复使用相同的列属性实例,但每一列都需要有自己的实例。

之前:

if (grid_->GetNumberRows() <= 0)
    {

    ///
    /// NO! The columns will share the same cell attribute
    /// instance.
    ///
    wxGridCellAttr* attr = new wxGridCellAttr();
    attr->SetReadOnly(true);
    attr->SetAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
    for (size_t i = 0; i<headers.size(); ++i)
        {

        if (grid_->GetNumberCols() <= 0)
            grid_->InsertCols();
        else
            grid_->AppendCols();


        grid_->SetColLabelValue(i, headers[i].data());
        grid_->SetColAttr(i, attr);
        }
    }

正确:

if (grid_->GetNumberRows() <= 0)
    {
    for (size_t i = 0; i<headers.size(); ++i)
        {

        if (grid_->GetNumberCols() <= 0)
            grid_->InsertCols();
        else
            grid_->AppendCols();


        grid_->SetColLabelValue(i, headers[i].data());

        ///
        /// Each column will have its own cell attribute.
        /// Supposedly, the column will take ownership of this
        /// instance.
        ///
        wxGridCellAttr* attr = new wxGridCellAttr();
        attr->SetReadOnly(true);
        attr->SetAlignment(wxALIGN_CENTRE, wxALIGN_CENTRE);
        grid_->SetColAttr(i, attr);
        }
    }

【讨论】:

  • 这确实是一个错误,但它无法解释崩溃。你的代码中有另一个错误。
  • 这绝对是崩溃的原因。我进行了测试,并且能够在一个只有上面代码的新项目中重现该问题。
  • 这似乎完全不可能,但我愿意被证明是错误的——请对 wxWidgets 中包含的grid sample 进行最小的更改以重现问题并打开Trac 票证。
猜你喜欢
  • 1970-01-01
  • 2017-07-09
  • 2018-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多