wxLogTextCtrl send too many logs to the wxTextCtrl, does wxTextCtrl have a row number limit
wxLogTextCtrl send too many logs to the wxTextCtrl, does wxTextCtrl have a row number limit
Hi, I have an application which use wxLogTextCtrl, and the application will runs for a long time, and there are many log messages send to the wxTextCtrl.
The question is: will the wxTextCtrl get a row number limit? What happens if it reaches the limit, will the old lines get automatically removed? Will the wxTextCtrl get slower if it has too many messages?
Any one has suggestions?
Thanks.
The question is: will the wxTextCtrl get a row number limit? What happens if it reaches the limit, will the old lines get automatically removed? Will the wxTextCtrl get slower if it has too many messages?
Any one has suggestions?
Thanks.
Re: wxLogTextCtrl send too many logs to the wxTextCtrl, does wxTextCtrl have a row number limit
1. That's really depend on your OS because wxWidgets is try to use native controls mostly.
Default value for wxTectCtrl under Windows is 64KB of text. So it would be better to use wxStyledTextCtrl instead. Another option - use virtual list control for each row where row is string that storage in std::vector<>.
2. I'm not totally sure, but I think after overflow new lines just won't be shown.
3. Yes.
Default value for wxTectCtrl under Windows is 64KB of text. So it would be better to use wxStyledTextCtrl instead. Another option - use virtual list control for each row where row is string that storage in std::vector<>.
2. I'm not totally sure, but I think after overflow new lines just won't be shown.
3. Yes.
Re: wxLogTextCtrl send too many logs to the wxTextCtrl, does wxTextCtrl have a row number limit
I think the answer my be platform specific.
AFAIK, on MSW, regular wxTextCtrl (without wxTE_RICH2) has a limit of 64 kB of text after which it probably crashes. With wxTE_RICH2, the theoretical limit is probably the RAM available. It will never remove any lines by itself.
However, I think in practice the user should limit the number of lines he adds to the control to some reasonable number. Either way, how the control behaves with very large amounts of text should be easy to test.
AFAIK, on MSW, regular wxTextCtrl (without wxTE_RICH2) has a limit of 64 kB of text after which it probably crashes. With wxTE_RICH2, the theoretical limit is probably the RAM available. It will never remove any lines by itself.
However, I think in practice the user should limit the number of lines he adds to the control to some reasonable number. Either way, how the control behaves with very large amounts of text should be easy to test.
Re: wxLogTextCtrl send too many logs to the wxTextCtrl, does wxTextCtrl have a row number limit
Thanks.
It is the Windows OS.
wxStyledTextCtrl may also have a content limit?Default value for wxTectCtrl under Windows is 64KB of text. So it would be better to use wxStyledTextCtrl instead.
OK, will try it.Another option - use virtual list control for each row where row is string that storage in std::vector<>.
This is not the expected behavior, I think the very old messages should be deleted.2. I'm not totally sure, but I think after overflow new lines just won't be shown.
OK, I see.3. Yes.
Re: wxLogTextCtrl send too many logs to the wxTextCtrl, does wxTextCtrl have a row number limit
Thanks, so when a wxLogMessage() like function get called, the wxTextCtrl should check the contents, if it exceed the limit, the old messages will be removed.PB wrote: ↑Sat Jan 02, 2021 7:48 am I think the answer my be platform specific.
AFAIK, on MSW, regular wxTextCtrl (without wxTE_RICH2) has a limit of 64 kB of text after which it probably crashes. With wxTE_RICH2, the theoretical limit is probably the RAM available. It will never remove any lines by itself.
However, I think in practice the user should limit the number of lines he adds to the control to some reasonable number. Either way, how the control behaves with very large amounts of text should be easy to test.
Is this way correct?
Re: wxLogTextCtrl send too many logs to the wxTextCtrl, does wxTextCtrl have a row number limit
All wxLogTextCtrl does is appending log messages to a wxTextCtrl. This is its full code
If you need something more, you need to implement it yourself.
Code: Select all
class WXDLLIMPEXP_CORE wxLogTextCtrl : public wxLog
{
public:
wxLogTextCtrl(wxTextCtrl *pTextCtrl);
protected:
// implement sink function
virtual void DoLogText(const wxString& msg) wxOVERRIDE;
private:
// the control we use
wxTextCtrl *m_pTextCtrl;
wxDECLARE_NO_COPY_CLASS(wxLogTextCtrl);
};
wxLogTextCtrl::wxLogTextCtrl(wxTextCtrl *pTextCtrl)
{
m_pTextCtrl = pTextCtrl;
}
void wxLogTextCtrl::DoLogText(const wxString& msg)
{
m_pTextCtrl->AppendText(msg + wxS('\n'));
}
Re: wxLogTextCtrl send too many logs to the wxTextCtrl, does wxTextCtrl have a row number limit
I think if you are going to reach such limits it would be better split log and put it in several files
wxStyledTextCtrl worked for me even when wxTectCtrl with rich flag wasn't. I found fixed bug for Scintilla (wxStyledTextCtrl is using Scintilla lib)Problems drawing very long lines where author tested ability on large SQL dumps.
Re: wxLogTextCtrl send too many logs to the wxTextCtrl, does wxTextCtrl have a row number limit
FWIW, wxTextCtrl with wxTE_RICH2 flag on Win10 seems to handle 1,000,000 lines mostly fine. The only issue seems to be manual resizing by mouse, probably caused by the long time the control takes to redraw?
However, I would generally not recommend having a million lines in a text control.
Code: Select all
#include <wx/wx.h>
class MyFrame: public wxFrame
{
public:
MyFrame() : wxFrame (nullptr, wxID_ANY, "Test")
{
const size_t lineCount = 1000 * 1000;
wxTextCtrl* logCtrl = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize,
wxTE_MULTILINE | wxTE_READONLY | wxTE_RICH2);
wxString logText;
for ( size_t i = 0; i < lineCount; ++i )
logText.Append(wxString::Format("This is a log line no %zu (and this is just a random filler text to make the line longer.\n", i));
logCtrl->AppendText(logText);
}
};
class MyApp : public wxApp
{
public:
bool OnInit() override
{
(new MyFrame())->Show();
return true;
}
}; wxIMPLEMENT_APP(MyApp);
Re: wxLogTextCtrl send too many logs to the wxTextCtrl, does wxTextCtrl have a row number limit
Thanks guys for the help, this is what I implemented:
Hope it can help others.
Code: Select all
/** a log control has content limit */
class LogTextCtrlLimit : public wxLogTextCtrl
{
public:
LogTextCtrlLimit(wxTextCtrl *pTextCtrl);
protected:
// implement sink function
virtual void DoLogText(const wxString& msg);
private:
// the control we use
wxTextCtrl *m_pTextCtrl;
int m_Counter;
wxDECLARE_NO_COPY_CLASS(LogTextCtrlLimit);
};
LogTextCtrlLimit::LogTextCtrlLimit(wxTextCtrl *pTextCtrl)
: wxLogTextCtrl(pTextCtrl), // we don't use the wxLogTextCtrl::pTextCtrl
m_pTextCtrl(pTextCtrl), // instead, we save the pointer here
m_Counter(0)
{
}
void LogTextCtrlLimit::DoLogText(const wxString& msg)
{
m_Counter++;
m_pTextCtrl->AppendText(msg + wxS('\n'));
if (m_Counter > 10000)
{
m_Counter = 0;
wxTextPos length = m_pTextCtrl->GetLastPosition();
if (length > 5000)
m_pTextCtrl->Remove(0, length - 5000);
}
}
Re: wxLogTextCtrl send too many logs to the wxTextCtrl, does wxTextCtrl have a row number limit
Why deriving from wxLogTextCtrl when you are not using any of its functionality? Would it not be better to derive directly from wxLog?
I personally would probably also remove the content based on the number of lines, not characters but...
I personally would probably also remove the content based on the number of lines, not characters but...
Re: wxLogTextCtrl send too many logs to the wxTextCtrl, does wxTextCtrl have a row number limit
Cool, glad to know - on Win10 works for me too(tested on 500,000), I had issue only under old version of Win7.
Nice, though I think it would be better to match between total amount of characters(value that passed into Remove method) and amount of messages in log (counter variable).
If you want to keep only N messages where N not very long and messages also not very big, I would use std::queue like this:
Code: Select all
void LogTextCtrlLimit::DoLogText(const wxString& msg)
{
m_queue.push(msg); //m_queue is member
m_pTextCtrl->AppendText(msg + '\n');
if (m_queue.size() > 100)
{
wxString old = m_queue.front();
m_pTextCtrl->Remove(0, old.size()+1); //+1 because '\n'
m_queue.pop();
}
}
to
Code: Select all
m_Counter += (msg.size()+1);
Re: wxLogTextCtrl send too many logs to the wxTextCtrl, does wxTextCtrl have a row number limit
Thanks, I also found this issue. First LogTextCtrlLimit was derive from wxLogTextCtrl, and I would like to access wxLogTextCtrl::m_pTextCtrl from my derived class LogTextCtrlLimit, unluckily, it is private (I have no way to access a base class's private member from derived class). Finally I add a same member variable LogTextCtrlLimit::m_pTextCtrl ...
Yes, you are correct, LogTextCtrlLimit should be derived from wxLog.
Yes, I agree, I prefer limit the number of lines, I just don't know how to do this.I personally would probably also remove the content based on the number of lines, not characters but...
Re: wxLogTextCtrl send too many logs to the wxTextCtrl, does wxTextCtrl have a row number limit
Thanks!Kvaz1r wrote: ↑Mon Jan 04, 2021 2:21 pmNice, though I think it would be better to match between total amount of characters(value that passed into Remove method) and amount of messages in log (counter variable).
If you want to keep only N messages where N not very long and messages also not very big, I would use std::queue like this:
Code: Select all
void LogTextCtrlLimit::DoLogText(const wxString& msg) { m_queue.push(msg); //m_queue is member m_pTextCtrl->AppendText(msg + '\n'); if (m_queue.size() > 100) { wxString old = m_queue.front(); m_pTextCtrl->Remove(0, old.size()+1); //+1 because '\n' m_queue.pop(); } }
Do you mean that "m_queue" only store the lengths of each msg?
If that is true, can we just use something like:
Code: Select all
m_queue.push(msg.size()); //m_queue is member
Code: Select all
std::queue<int>
OK, I see this method, so basically limit the total characters are simple than limit lines.if you want count only characters - replace in your code m_Counter++;
toCode: Select all
m_Counter += (msg.size()+1);
Re: wxLogTextCtrl send too many logs to the wxTextCtrl, does wxTextCtrl have a row number limit
In this case, Flush() should probably be implemented as well?
Re: wxLogTextCtrl send too many logs to the wxTextCtrl, does wxTextCtrl have a row number limit
wxTextCtrl has GetNumberOfLines(), GetLineLength(), and Remove() so it theory it should be possible to implement. However, I do not know how fast it would be when the log is really long.