wxTxtCtrl problem Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
Post Reply
BobS0327
Knows some wx things
Knows some wx things
Posts: 27
Joined: Wed May 10, 2006 3:51 pm

wxTxtCtrl problem

Post by BobS0327 »

I am using wxWidget 2.6.3 with Linux Fedora Core 5 OS and Windows XP Pro OS. Essentially, I'm writing a cross platform app.

My problem code:

Code: Select all

wxTextCtrl *key1;
key1 = new wxTextCtrl(this, KeyText1,wxEmptyString , wxPoint(110, 180), wxSize(180, 30),wxTE_PROCESS_ENTER  );

    key1->SetToolTip( _T("First part of key. Example B5-56-A9-C3-34-D2-49-FE") );

    key1->SetMaxLength(23);
If I attempt any of the following statements in the Linux version, I get a segmentation fault:

Code: Select all

wxString tinput = "testing";
key1->SetValue(tinput);
key1->Append(tinput);
key1->AppendText(tinput);
(*key1) << tinput;
But I do not encounter any problems in the Windows version when I try to input text to the wxTextCtrl.

Anybody have any solutions or suggestions?

Thanx

Bob
KevinHock
Filthy Rich wx Solver
Filthy Rich wx Solver
Posts: 236
Joined: Sat Sep 04, 2004 1:49 pm
Location: Ohio, USA
Contact:

Post by KevinHock »

Can you post a backtrace or debugger output on the crash?
BobS0327
Knows some wx things
Knows some wx things
Posts: 27
Joined: Wed May 10, 2006 3:51 pm

Post by BobS0327 »

The GDB output:

Code: Select all

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread -1208371504 (LWP 4413)]
0x080709cd in wxWindowBase::Disable (this=0x0)
    at /usr/local/include/wx-2.6/wx/window.h:453
453         bool Disable() { return Enable(false); }
(gdb) backtrace
#0  0x080709cd in wxWindowBase::Disable (this=0x0)
    at /usr/local/include/wx-2.6/wx/window.h:453
#1  0x0805a45d in BasicPanel::OnTextEnter (this=0x94f6d48) at minimal.cpp:2305
#2  0x081e12ce in wxEvtHandler::ProcessEventIfMatches ()
#3  0x081e13f3 in wxEventHashTable::HandleEvent ()
#4  0x081e1564 in wxEvtHandler::ProcessEvent ()
#5  0x08114697 in wxWindowBase::TryParent ()
#6  0x081e1509 in wxEvtHandler::ProcessEvent ()
#7  0x080da951 in gtk_text_changed_callback ()
#8  0x001171c9 in g_cclosure_marshal_VOID__VOID ()
   from /usr/lib/libgobject-2.0.so.0
#9  0x00109f6d in g_closure_invoke () from /usr/lib/libgobject-2.0.so.0
#10 0x0011aa3d in g_signal_override_class_closure ()
   from /usr/lib/libgobject-2.0.so.0
#11 0x0011bf47 in g_signal_emit_valist () from /usr/lib/libgobject-2.0.so.0
#12 0x0011dd7e in g_signal_emit_by_name () from /usr/lib/libgobject-2.0.so.0
#13 0x05abc6fc in gtk_entry_new () from /usr/lib/libgtk-x11-2.0.so.0
#14 0x05b2c144 in gtk_marshal_BOOLEAN__VOID ()
   from /usr/lib/libgtk-x11-2.0.so.0
#15 0x00108817 in g_value_set_static_boxed () from /usr/lib/libgobject-2.0.so.0
#16 0x00109f6d in g_closure_invoke () from /usr/lib/libgobject-2.0.so.0
#17 0x0011b083 in g_signal_override_class_closure ()
   from /usr/lib/libgobject-2.0.so.0
---Type <return> to continue, or q <return> to quit---
BobS0327
Knows some wx things
Knows some wx things
Posts: 27
Joined: Wed May 10, 2006 3:51 pm

Post by BobS0327 »

I found the source of my problem. I just don't know how to fix it. The btnAdd2DB->Disable() causes the fault.

Code: Select all

void BasicPanel::OnTextEnter(wxCommandEvent& WXUNUSED(event))
{
        if(description->GetLineLength(0) > 0  && ipaddress->GetLineLength(0) > 0  && port->GetLineLength(0) > 0 && password->GetLineLength(0) > 0 && key1->GetLineLength(0) > 0 && key2->GetLineLength(0) > 0)
        btnAdd2DB->Enable();
    else
        btnAdd2DB->Disable();
}
benedicte
wxWorld Domination!
wxWorld Domination!
Posts: 1409
Joined: Wed Jan 19, 2005 3:44 pm
Location: Paris, France

Post by benedicte »

How is btnAdd2DB initialized??

Is it a member of your "BasicPanel" class?
BobS0327
Knows some wx things
Knows some wx things
Posts: 27
Joined: Wed May 10, 2006 3:51 pm

Post by BobS0327 »

It is initialized as follows:

Code: Select all

 wxButton *btnAdd2DB;
  btnAdd2DB     = new wxButton( this, AddRecord2DB, "Add Record to Database", wxPoint(350,130), wxSize(180,30));
    btnAdd2DB->Disable();
	
The button is initially disabled until all the wxTextCtrl's contain data, at which time it is enabled.

btnAdd2DB is part of my BasicPanel class.
benedicte
wxWorld Domination!
wxWorld Domination!
Posts: 1409
Joined: Wed Jan 19, 2005 3:44 pm
Location: Paris, France

Post by benedicte »

If you declared btnAdd2DB as a class member but also as a local variable in your constructor, it won't work.

Code: Select all

class BasicPanel: public wxPanel
{
public:
   BasicPanel (*params*) ;
// ...

protected:
   wxButton *btnAdd2DB;
// ...
};

// ...
BasicPanel::BasicPanel (*params*)
{
// ...

// note that btnAdd2DB is not declared here.
  btnAdd2DB     = new wxButton( this, AddRecord2DB, "Add Record to Database", wxPoint(350,130), wxSize(180,30));
    btnAdd2DB->Disable();
}
BobS0327
Knows some wx things
Knows some wx things
Posts: 27
Joined: Wed May 10, 2006 3:51 pm

Post by BobS0327 »

Oops, sorry. btnAdd2DB is declared as a class member not a local variable.
BobS0327
Knows some wx things
Knows some wx things
Posts: 27
Joined: Wed May 10, 2006 3:51 pm

Post by BobS0327 »

I've include a complete sample of my problem. This code compiles and runs fine. But if I uncomment the int y = text2->GetLineLength(0); statement, I will get a segmentation fault error. Anybody have any ideas on why this is happening and possibly a resolution?

Thanx

Code: Select all

#include "wx/wxprec.h"
#ifdef __BORLANDC__
    #pragma hdrstop
#endif
#ifndef WX_PRECOMP
    #include "wx/wx.h"
#endif

class BasicPanel : public wxPanel
{
public:
    BasicPanel(wxFrame* parent,int x, int y, int w, int h);
    ~BasicPanel( );
    void OnTextEnter(wxCommandEvent& WXUNUSED(event));
   
    wxTextCtrl *text1;
    wxTextCtrl *text2;
   
    DECLARE_EVENT_TABLE()
};

enum
{
    Static_Text = wxID_HIGHEST+5000,
    Text1Input,
    Text2Input,
   };
BEGIN_EVENT_TABLE(BasicPanel,wxPanel)
EVT_TEXT( wxID_ANY, BasicPanel::OnTextEnter )
END_EVENT_TABLE()

BasicPanel::BasicPanel(wxFrame* parent,int x, int y, int w, int h) : wxPanel(parent, wxID_ANY, wxPoint(x, y), wxSize(w, h) )  
{
    text1 = new wxTextCtrl(this, Text1Input, wxEmptyString, wxPoint(110, 20), wxSize(180, 30),wxTE_PROCESS_ENTER );
    text1->SetMaxLength(23);
    text1->SetFocus();
	text1->SetValue("Text Control 1");  
    text2 = new wxTextCtrl(this, Text2Input, wxEmptyString, wxPoint(110, 60), wxSize(180, 30),wxTE_PROCESS_ENTER );
    text2->SetMaxLength(23);
 	text2->SetValue("Text Control 2");    
}

BasicPanel::~BasicPanel( ) {}

wxPanel *thePanel;

class MyApp : public wxApp
{
public:
    virtual bool OnInit();
};

class MyFrame : public wxFrame
{
public:
    MyFrame(const wxString& title);
    void OnQuit(wxCommandEvent& event);
private:
    DECLARE_EVENT_TABLE()
};

enum
{
    Minimal_Quit = wxID_EXIT,
};

BEGIN_EVENT_TABLE(MyFrame, wxFrame)
    EVT_MENU(Minimal_Quit,  MyFrame::OnQuit)
END_EVENT_TABLE()

IMPLEMENT_APP(MyApp)

bool MyApp::OnInit()
{
    MyFrame *frame = new MyFrame(_T("wxWidgets wxTextCtrl bug App"));
    frame->Show(true);
    return true;
}

MyFrame::MyFrame(const wxString& title)
       : wxFrame(NULL, wxID_ANY, title)
{
  	thePanel = new BasicPanel(this, 0,100,300,330);

#if wxUSE_STATUSBAR
    CreateStatusBar(2);
    SetStatusText(_T("Possible wxTextCtrl bug"));
#endif 
}

void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
{
    Close(true);
}

void BasicPanel::OnTextEnter(wxCommandEvent& WXUNUSED(event))
{
	int x = text1->GetLineLength(0);
//	int y = text2->GetLineLength(0);
}
DavidHart
Site Admin
Site Admin
Posts: 4252
Joined: Thu Jan 12, 2006 6:23 pm
Location: IoW, UK

Post by DavidHart »

Hi,

The segfault is because text2 is null in int y = text2->GetLineLength(0);

The reason that it's null is the sort of thing that only a debugger can tell you: I'm not surprised nobody managed to work it out from the code. You create text1 in the BasicPanel ctor, and immediately call text1->SetValue("Text Control 1"); No problem. You then go on to create text2. However you also handle EVT_TEXT, which is triggered by the SetValue() call, and in its handler you do text2->GetLineLength as above. As text2 hasn't yet been constructed...

Why did it work in MSWin? Presumably events loop more slowly there, and by the time the handler was called text2 had had time to get real.

The easy solution: create text1 and text2, and only then do SetValue().

Regards,

David
BobS0327
Knows some wx things
Knows some wx things
Posts: 27
Joined: Wed May 10, 2006 3:51 pm

Post by BobS0327 »

David,

First of all I just to say that I'm a wxWidgets newbie. So, I misunderstood how all my code works. My reasoning on how it should work was really off on a tangent.

Thanx for explaining the problem and providing a resolution.

Bob
Post Reply