【问题标题】:fill database table in wxListCtrl using wxThread- i can fill but system is going to hang使用 wxThread 填充 wxListCtrl 中的数据库表 - 我可以填充但系统将挂起
【发布时间】:2011-02-17 12:38:58
【问题描述】:

首先我制作了一个在 wxListCtrl 中显示表格的程序,它可以工作,但数据量有限.. 它显示了一个问题,例如:- 当我执行程序时。框架在一段时间后可见......但它有效 然后我转向使用 wxThread 现在一切都很好,现在当我执行程序框架时立即可见,因为我写了 Sleep(1000),所以它在 wxListCtrl 中一一添加一行,但它给出了意外的结果取决于有多少行在数据库中.. 我的代码是:-

# include "thread.h"
# include "login.h"
# include "sql.h"
# include <mysql.h>

class List_Ctrl_Data;

MyThread :: MyThread(login* login_obj)
{
     this->temp = login_obj;
}
void *MyThread :: Entry()
{
    int i=1,j,k=0   ;
    while(i!=100)
    {
            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==1)
            {
                            k=10;
                       this->Sleep(1000);
            }
            i++;                                                
    }
}

这里 data_list_control 是 wxListCtrl 的对象,借助线程 i 在 wxListCtrl 内部填充值。 有些人告诉我,你在这里一次又一次地从线程入口敲框架控件(wxListCtrl), 这就是为什么框架被绞死的原因,您应该为此使用 wxPost 或 AddPendingRequest,我认为它不会起作用, 我试图向你解释我的问题,但你仍然想问任何问题,欢迎你..如果你能帮助我,对我来说会很重要

【问题讨论】:

标签: c++ wxwidgets


【解决方案1】:

您看到的问题可能是由于您从辅助线程而不是主线程调用 GUI 控件上的方法。这应该永远做。您需要从主线程添加项目。

我猜您尝试从辅助线程执行此操作的原因之一是因为添加大量项目需要很长时间,并且它会挂起您的用户界面。正确的方法是使用虚拟列表控件(如@Erik 提到的“重复”问题中所述),或者在添加项目时定期调用 wxYield(或 wxSafeYield)以便处理 UI 事件。

【讨论】:

    【解决方案2】:

    ********************************解决方案在这里**** **************

    我在线程中使用了代码,例如[它从数据库中获取一行并传递给事件] void *MyThread :: Entry()

    {
    
        List_Ctrl_Data obj1 ;
        MYSQL_RES *database_table_data;
        database_table_data=obj1.getdata();
        MYSQL_ROW row;
        while((row=mysql_fetch_row(database_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);
    
            }
    
    
    }
    

    为了处理这个,我们创建了一个事件表和一个函数来处理这个值—— 无效 onNumberUpdate(wxCommandEvent& evt); 私人的: DECLARE_EVENT_TABLE() 在头文件和cpp文件中我们写

    无效登录::onNumberUpdate(wxCommandEvent& evt)

    {
    
        int i=0,j;
    
        void* hold_row;
    
        hold_row=(void *)evt.GetClientData();
    
        MYSQL_ROW row;
    
        row=(MYSQL_ROW)hold_row;
    
        //while(row!=NULL)
    
        //{
    
            //wxPuts(wxT("kjhjkh"));
    
            const char* chars1 = row[0];
    
            wxString mystring1(chars1, wxConvUTF8);
    
            long index=data_list_control->InsertItem(this->counter,mystring1);
        this->counter++;
    
            for(j=1;j<3;j++)
    
                {
    
                const char* chars2=row[j];
    
                wxString mystring2(chars2,wxConvUTF8);
    
                data_list_control->SetItem(index,j,mystring2);
                }
    
        //}
    
    }
    

    BEGIN_EVENT_TABLE(登录,wxFrame) EVT_COMMAND (100000, wxEVT_COMMAND_TEXT_UPDATED, login::onNumberUpdate)

    END_EVENT_TABLE()

    终于解决了我的问题//////

    www.rohitworld.site90.net 或 ROHITAMITPATHAK@GMAIL.COM

    【讨论】:

    • 我想这是可行的,但请注意,为数据库表中的每一行生成和发布事件会对性能造成巨大影响。这可以显着优化。
    • 此外,虽然在这里使用 wxEVT_COMMAND_TEXT_UPDATED 不会造成任何损害,但通常不建议将现有的内置事件类型重新用于完全不同的目的。定义自己的自定义事件类型并不难。
    猜你喜欢
    • 1970-01-01
    • 2021-06-30
    • 1970-01-01
    • 1970-01-01
    • 2021-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多