Консультация № 70404
11.01.2007, 01:14
0.00 руб.
0 1 1
У меня вопрос, касающийся C++ и библиотеки Qt.
У меня есть простой Widget, на котором я рисую графику (неважно какую).

Раньше я делал просто: в одном классе Widget совмещал код рисования и код обработки (т.е. совмещал вид и контроллер). Делал примерно так: создаю нулевой таймер (когда очередь сообщений пуста) и на этот таймер вешаю код обработки графики. Пример в приложении 1.

Теперь я хочу разъединить эти вещи. Первое, что приходит на ум, да и советуют многие – это потоки. Поток подготавливает кадр, а окно показывает. Это правильно, или я в чём-то ошибаюсь? Ситуация осложняется тем, что у меня нет прямого доступа к функции перерисовки окна (paintEvent). И надо помнить о синхронизации. Примерный код в приложении 2.

Теперь суть вопроса. Код из прил.2 работает некорректно. Плохо со синхронизацией, окно плохо «слушается», и вообще просто плохо :)
Может кто-нибудь подскажет идею или, хотя бы, направление, в котором стоит двигаться?


Приложение:
// Приложение 1. С таймером.class Window: public QWidget{Graphics graphics;public: Window() { QTimer* idleTimer = new QTimer(this); connect(idleTimer, SIGNAL(timeout()), this, SLOT(idle())); }protected: virtual void paintEvent(QPaintEvent* event) { QPainter painter(this); graphics.paint(painter); }private slots: void idle() { graphics.process(); repaint(); // вызывает paintEvent }};// Приложение 2. С потоком.class Window: public QWidget{ public: Window() {}signals: void painting(QPainter& painter);protected: virtual void paintEvent(QPaintEvent* event) { QPainter painter(this); emit painting(painter); }};class Control: public QThread{ Window window; Graphics graphics;public: Control() { connect(&window, SIGNAL(painting(QPainter&)), &graphics, SLOT(paint(QPainter&))); connect(this, SIGNAL(needToProcess()), &graphics, SLOT(process())); connect(this, SIGNAL(needToRepaint()), &window, SLOT(update())); }signals: void needToProcess(); void needToRepaint();protected: virtual void run() { while (/*усл. выхода*/) { //if (!qApp->hasPendingEvents()) { emit needToProcess(); // непосредственно вызвать update() нельзя, // т.к. Widget нереентабельный и обращаться // к нему напрямую из другого потока нельзя. emit needToRepaint(); //} else qApp->processEvents(); } }};

Обсуждение

Неизвестный
11.01.2007, 23:41
общий
это ответ
Здравствуйте, V1s0r!
ваш случай
http://cartan.cas.suffolk.edu/qtdocs/threads-mandelbrot.html

The application consists of two classes:
* RenderThread is a QThread subclass that renders the Mandelbrot set.
* MandelbrotWidget is a QWidget subclass that shows the Mandelbrot set on screen and lets the user zoom and scroll.
Форма ответа