如何使用wxThread的概念在wxListCtrl中显示大数据

时间:2011-02-14 13:29:46

标签: c++ wxwidgets

我能够在wxListCtrl中填充数据库表, 我的问题是处理大范围的数据,我想在线程概念的帮助下这样做,也许它会因为大量的数据而保存挂起帧。 我是线程概念的新手,所以你的单行将成为我的书。

更新

我的问题是如何使用wxThread的概念在wxListCtrl中显示大数据 所以对于这个我用线程概念我添加了两个文件thread.c和thread.cpp 我的输入线程代码如下所示

void *MyThread :: Entry()
{
    int i=1,j,k=0;
    while(i!=400)
    {
        long index=this->temp->data_list_control->InsertItem(i,wxT("amit"));
        for(j=1; j<3; j++) {
            this->temp->data_list_control->SetItem(index,j,wxT("pathak"));
        }

        k++;

        if(k==30) {
            this->Sleep(1000);
            k=0;
        }
        i++;
    }
}

它有时工作正常,但当我尝试增加i的值时,它会显示错误,如

-*showingdatainwxlistctrl: ../../src/XlibInt.c:595: _XPrivSyncFunction: Assertion `dpy->synchandler == _XPrivSyncFunction' failed.*

或者有时会出现错误,如

***[Xcb] xcb_io.c:378: _XAllocID: Assertion `ret != inval_id' failed***

为什么会发生在我身上?

2 个答案:

答案 0 :(得分:1)

您可以通过以下方式在wxWidgets中定义自己的线程对象:

class MyThread : public wxThread
{
private:
    wxListCtrl* m_pListCtrl;
public:
    MyThread(wxListCtrl* pListCtrl, wxThreadKind kind = wxTHREAD_DETACHED) : 
        wxThread(kind), m_pListCtrl(pListCtrl) {
    }
    virtual ~MyThread() {
    }
    virtual void* Entry() {
        // here you have to place your code that will be running in separate thread
        // m_pListCtrl-> ...
    }
};

这就是你如何开始你的线程(假设你有pListCtrl指针):

MyThread * pMyThread = new MyThread (pListCtrl);
wxThreadError ThreadError = pMyThread->Create();
if (wxTHREAD_NO_ERROR!=ThreadError) {
    wxLogError(L"Can not create thread, wxThreadError '%d'", (int)ThreadError);
    delete pMyThread;
    return false;
}
ThreadError = pMyThread->Run();
if (wxTHREAD_NO_ERROR!=ThreadError) {
    wxLogError(L"Can not run thread, wxThreadError '%d'", (int)ThreadError);
    delete pMyThread;
    return false;
}
// here, everything is ok.

无论如何,这不是解决问题的最佳方案。据我所知,你需要在wxListCtrl中显示大量数据。为此,您可以使用虚拟ctrl(使用标志wxLC_VIRTUAL创建)并提供数据源:

class MyListCtrl : public wxListCtrl
{

public:
    MyListCtrl( ...) { ... }
    virtual ~MyListCtrl();
protected:
    virtual int OnGetItemImage(long item) const {
        // You need this only if you want to provide specific image for your item.
        // If you do not need it, just do not overload this method.
    }
    virtual wxString OnGetItemText(long item, long column) const {
        // This is where you have to provide data for [item, column].
        // Suppose, you have matrix A[n,m] which represents actually the data
        // you want to display. The elements of this matrix can be of any type
        // (strings, doubles, integers etc). 
        // You should return here wxString object that contains 
        // representation of the matrix's element A[item, column].
        return ToWxString(A[item, column]);
        // where ToWxString is your method that converts data to string
        // So, you do not need to load all the data from A to wxListCtrl.
        // Instead of it, wxListCtrl will determine which rows of the matrix should be
        // displayed based on sizes and scroll position of wxListCtrl, and will 
        // call this method to obtain corresponding strings.
    }
};

要创建,您可以使用:

m_pListCtrl = new MyListCtrl( ..., ..., wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_VIRTUAL | wxSUNKEN_BORDER | wxLC_VRULES | wxLC_HRULES);

祝你好运!

答案 1 :(得分:0)

  1. 当您执行大范围的数据时,您必须在程序中使用WXThread
  2. 首先是试图从wxEntry点填充wxListCtrl,这是错误的你不能从入口点击任何主线程控制,它不会给出错误,但这是一个错误的概念
  3. 这里你需要将数据传递给handler,handler会用它来填充wxListCtrl 代码看起来像这样 - &gt;

    void * MyThread :: Entry() {     int a;     处理程序handler_obj;     char * database_name = DATABASE_NAME;     connection = handler_obj.handler(101,database_name);     如果(连接== NULL)     {       wxMessageBox(wxT(“CAN not CONNECT TO DATABASE”),wxT(“Message”),wxOK | wxICON_INFORMATION,NULL,-1,-1);     }     其他     {         List_Ctrl_Data list_ctrl_data_object;         TABLE_DATA = list_ctrl_data_object.fetch_table(连接);

        MYSQL_ROW row;
        while((row=mysql_fetch_row(table_data))!=NULL)
            {
    
                wxCommandEvent event( wxEVT_COMMAND_TEXT_UPDATED, 100000 );
                void *row_data;
                row_data=(void *)row;
                event.SetClientData(row_data);
                temp->GetEventHandler()->AddPendingEvent( event );
                this->Sleep(1000);
            }
    }
    

    }

  4. 处理我们将使用的行数据

    void Id_Search_Report::onNumberUpdate(wxCommandEvent& evt)
        {
            int j;
            void* hold_row;
            hold_row=(void *)evt.GetClientData();
            MYSQL_ROW row;
            row=(MYSQL_ROW)hold_row;
    
                const char* chars1 = row[0];
                wxString mystring1(chars1, wxConvUTF8);
                long index=data_list_control->InsertItem(this->counter,mystring1);
            this->counter++;
                for(j=1;j<12;j++)
                    {
                    const char* chars2=row[j];
                    wxString mystring2(chars2,wxConvUTF8);
                    data_list_control->SetItem(index,j,mystring2);
                    }
    
        }
    

    线程正在返回一行,此方法将处理行并填充ListCtrl,这是一种填充wxListCtrl的正确方法。