问题
I'm capable to fill the database table in wxListCtrl, my problem is to handle high range of data, I want to do this with the help of thread concept , perhaps it will save to hang the frame because of high amount of data. I'm new in thread concept so your single lines will be a book for me.
Update:
My question was- how to display large data in wxListCtrl with using concept of wxThread so for this I used thread concept I add two more files thread.c and thread.cpp my entry thread code is shown below
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++;
}
}
It is sometimes working fine but when I try to increase the value of i
, it shows an error like
-*showingdatainwxlistctrl: ../../src/XlibInt.c:595: _XPrivSyncFunction: Assertion `dpy->synchandler == _XPrivSyncFunction' failed.*
or sometime it gives error like
***[Xcb] xcb_io.c:378: _XAllocID: Assertion `ret != inval_id' failed***
Why it is happening to me?
回答1:
You can define your own thread object in wxWidgets in the following way:
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-> ...
}
};
And this is the way how you can start your thread (assume you have your pListCtrl pointer here):
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.
Anyway, this is not the best solution for your problem. As far as I've understood, you need to display large amount of data in your wxListCtrl. To do this, you can use virtual ctrl (created with flag wxLC_VIRTUAL) and provide data source:
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.
}
};
To create, you may use:
m_pListCtrl = new MyListCtrl( ..., ..., wxLC_REPORT | wxLC_SINGLE_SEL | wxLC_VIRTUAL | wxSUNKEN_BORDER | wxLC_VRULES | wxLC_HRULES);
Best regards!
回答2:
- When you are performing high range of data you are bound to use WXThread in your program
- Firstly was trying to fill wxListCtrl from wxEntry point, it was wrong u can not hit any main thread control from entry point, it does not give error, but it is a wrong concept
Here u need to pass the data to handler, handler will use it to fill wxListCtrl code look like this->
void *MyThread :: Entry() { int a; Handler handler_obj; char *database_name=DATABASE_NAME; connection =handler_obj.handler(101,database_name); if(connection==NULL) { wxMessageBox(wxT("CAN NOT CONNECT TO DATABASE"), wxT("Message"), wxOK | wxICON_INFORMATION, NULL, -1, -1); } else { 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); } }
}
to handle the row data we will use
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);
}
}
thread is returning a row , this method will handle the row and fill ListCtrl , it is a proper way to fill wxListCtrl.
来源:https://stackoverflow.com/questions/4992690/how-to-display-large-data-in-wxlistctrl-with-using-concept-of-wxthread