C ++ WxWidgets: перенаправление Stdout в wxTextCtrl через несколько потоков - PullRequest
0 голосов
/ 15 июля 2009

Мое приложение - это многопоточное приложение (с использованием wxThreads). На данный момент основной поток вместе с дочерними рабочими потоками выводит различные сообщения в Stdout (используя cout).

У меня есть новый фрейм / окно с wxTextCtrl, и я хотел бы перенаправить все сообщения StdOut в него.

GuiLogFrame         *logframe;

logframe = new GuiLogFrame(NULL, wxID_ANY, wxEmptyString);
logframe->Show();

logredirector = new wxStreamToTextRedirector(logframe->get_log_textctrl());

Это не работает. Но если я заменю последнюю строку

wxStreamToTextRedirector redir(logframe->get_log_textctrl());

Стандартный выход будет перенаправлен на логический кадр wxTextCtrl, пока redir находится в области видимости ... Я хочу, чтобы он оставался, даже если он выходит за пределы области видимости.

Я хочу, чтобы wxStreamToTextRedirector оставался нетронутым в течение всего времени работы приложения ... так что даже cout нового потока будет также перенаправляться на тот же wxTextCtrl.

Есть мысли?

Ответы [ 3 ]

1 голос
/ 28 июля 2009

Важно знать, что операции с графическим интерфейсом должны выполняться только в основном потоке; если вы этого не сделаете, он будет зависать или зависать, когда у вас одновременно будет несколько операций с графическим интерфейсом. Это определенно верно для Windows, но я считаю, что это относится ко всем платформам. Что вам нужно сделать, это опубликовать событие в элементе управления с помощью GetEventHandler () -> AddPendingEvent. Затем wx добавит событие в очередь объекта и при запуске основного потока может выполнить операцию с графическим интерфейсом.

Возможно, это не точный ответ на ваш вопрос, но это важная информация.

0 голосов
/ 05 декабря 2012

wxStreamToTextRedirector - это класс RAII, связывающий поток с текстовым элементом управления в его ctor и нарушающий ассоциацию в его dtor. Конечно, вы можете создать его в куче, вместо того, чтобы использовать его в качестве локальной переменной или даже просто вручную сделать то, что делает его ctor / dtor, то есть вызвать ostr.rdbuf(text) и восстановить исходное значение rdbuf() в более позднее время.

Однако, как писал arolson101, у вас все равно может возникнуть проблема в вашем коде, если вы разрешите нескольким потокам использовать один и тот же wxTextCtrl, и простое перенаправление не поможет вам в этом. Вам нужно написать свой собственный класс streambuf -приобретенный, который позволит избежать вывода текста сразу, но отправит сообщение в основной поток GUI с просьбой сделать это, что не совсем тривиально.

0 голосов
/ 13 декабря 2010

Я нашел один способ сделать это, но я не пробовал его в многопоточном приложении.

Вы можете создать указатель на wxStreamToTextRedirector в конструкторе (), используя new. И затем, не забудьте удалить указатель в деструкторе.

...