6773f9b29e
三段式对比直击 Day4 slides「主线程耗时=冻结」痛点:主线程渲染冻结 / 后台单线程不卡但慢 / 后台多线程不卡且快。 - QThreadPool + QRunnable 分水平条带并行,排队信号槽回传,epoch 版本号防过期覆盖 - wheelEvent 缩放(鼠标为锚)+ mouseEvent 拖拽平移 + paintEvent 画 QImage - 子目录自带独立 CMakeLists.txt,可单独构建/共享(双模式约定同 lineedit_eye_toggle) - 配套 README(概念/走读/双构建/5 踩坑点/练习)+ 设计规格 - 已验证:独立工程 offscreen 运行 exit=0;主工程构建 exit=0(w64devkit g++16 + mingw73 Qt5.14.2) 注:主工程 examples/CMakeLists.txt 的接入(mandelbrot + lineedit_eye_toggle + qdialog + themes 原子接入)与顶层 CMakeLists 本地调试改动未一并提交,待整体确认后单独提交。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
60 lines
2.4 KiB
C++
60 lines
2.4 KiB
C++
// ============================================================================
|
||
// mandelbrot_widget —— Day4 Mandelbrot 渲染器的交互与渲染调度主体(QWidget)
|
||
// 职责:
|
||
// * paintEvent : 把累积 QImage 一次性画到窗口(QPainter 绘图知识点)
|
||
// * wheelEvent/mouse* : 滚轮缩放(以鼠标为锚)、左键拖拽平移(事件处理知识点)
|
||
// * scheduleRender() : 切水平条带丢 QThreadPool 并行算(多线程知识点)
|
||
// * onStripReady() : 收条带、拼图、版本号防过期、耗时显示
|
||
// * onRenderOnMainThread() : 「主线程渲染」按钮——同步算整帧,演示事件循环被
|
||
// 占用即界面冻结(直击 Day4 slides「主线程耗时=冻结」痛点)
|
||
// * onToggleThreadMode() : 复用同一套分块逻辑,切线程池大小,对比单/多线程加速比
|
||
// ============================================================================
|
||
#ifndef MANDELBROT_WIDGET_H
|
||
#define MANDELBROT_WIDGET_H
|
||
|
||
#include <QElapsedTimer>
|
||
#include <QImage>
|
||
#include <QPoint>
|
||
#include <QWidget>
|
||
|
||
#include "mandelbrot_strip_task.h" // MandelViewport / MandelPalette
|
||
|
||
class QLabel;
|
||
|
||
class MandelbrotWidget : public QWidget {
|
||
Q_OBJECT
|
||
public:
|
||
explicit MandelbrotWidget(QWidget* parent = nullptr);
|
||
|
||
protected:
|
||
void paintEvent(QPaintEvent*) override;
|
||
void wheelEvent(QWheelEvent*) override;
|
||
void mousePressEvent(QMouseEvent*) override;
|
||
void mouseMoveEvent(QMouseEvent*) override;
|
||
void mouseReleaseEvent(QMouseEvent*) override;
|
||
void resizeEvent(QResizeEvent*) override;
|
||
|
||
private slots:
|
||
void onStripReady(quint64 epoch, int stripIndex, QImage strip);
|
||
void onRenderOnMainThread(); // 卡死演示
|
||
void onToggleThreadMode(); // 单/多线程切换
|
||
|
||
private:
|
||
void scheduleRender(); // ++epoch + 分块丢池
|
||
|
||
MandelViewport vp_;
|
||
MandelPalette pal_;
|
||
QImage pixmap_; // 累积画布(离屏 QImage,paintEvent 外对它构造 QPainter 合法)
|
||
quint64 epoch_ = 0; // 渲染版本号:新视口令旧结果作废丢弃(防过期覆盖)
|
||
int stripsTotal_ = 0;
|
||
int stripsDone_ = 0;
|
||
QElapsedTimer timer_;
|
||
bool multiThread_ = true;
|
||
int threadCount_ = 0;
|
||
bool dragging_ = false;
|
||
QPoint lastMouse_;
|
||
QLabel* label_ = nullptr;
|
||
};
|
||
|
||
#endif // MANDELBROT_WIDGET_H
|