【问题标题】:how to display large data in wxListCtrl with using concept of wxThread如何使用 wxThread 的概念在 wxListCtrl 中显示大数据
【发布时间】:2011-02-14 13:29:45
【问题描述】:

我能够在 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***

为什么会发生在我身上?

【问题讨论】:

    标签: c++ wxwidgets


    【解决方案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);
    

    最好的问候!

    【讨论】:

    • 首先-我想说“非常感谢您对我的这种关注”,并根据您的建议说我写了一些代码行它确实有效,但有时它会失败......我无法在此评论区显示代码,所以我要搜索另一个地方,在那里我可以显示“我做了什么”我得到了什么错误..
    • 我读到你不应该直接与主线程控制通信,我在我的程序中使用 wxListCtrl,这就是为什么程序给出了不希望的结果,我认为我应该使用 AddPendingEvent,但是如何?
    【解决方案2】:
    1. 当您执行大量数据时,您必须在程序中使用 WXThread
    2. 首先尝试从 wxEntry 点填充 wxListCtrl,这是错误的 u can't hit any main thread control from entry point,它没有报错,但这是一个错误的概念
    3. 这里你需要将数据传递给handler,handler会用它来填充wxListCtrl 代码如下->

      void *MyThread :: Entry() { 诠释一个; 处理程序 handler_obj; 字符 *database_name=DATABASE_NAME; 连接 =handler_obj.handler(101,database_name); 如果(连接==NULL) { wxMessageBox(wxT("不能连接到数据库"), wxT("消息"), wxOK | wxICON_INFORMATION, NULL, -1, -1); } 别的 { List_Ctrl_Data list_ctrl_data_object; table_data=list_ctrl_data_object.fetch_table(connection);

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

      }

    处理我们将使用的行数据

    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的正确方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多