QImage调整大小事件

时间:2018-01-30 11:57:45

标签: c++ qt qimage

我有一个简单的绘图应用程序,但是当我调整窗口大小时,图像被删除了,我想保留它。我尝试使用image.scaled(当前大小),但它不起作用。

qDebug() << "Resized.";

CurrentSize = event->size();

QImage newImage(CurrentSize, QImage::Format_RGB32);
Image = newImage;
Image.fill(Qt::white);
IsDrawing = false;

this->update();

2 个答案:

答案 0 :(得分:2)

我假设你提供的代码在一个方法中,在这种情况下,在堆栈上创建newImage,并在退出方法时超出范围(并调用析构函数)。

在堆上创建它(new QImage)将阻止这种情况,但是您需要管理对象的生命周期。 Qt的parent通常对此有所帮助。

答案 1 :(得分:0)

我不知道&#34;简单&#34;你的简单油漆应用程序是,但我觉得你过度复杂化了一些东西。

假设我们对绘制画布小部件有以下要求:

  1. 图像大小跟踪小部件大小,并通过裁剪而不是重新缩放来实现。
  2. 小部件可以自由更改其大小。
  3. 可选地,图像永远不会缩小。默认设置此选项。
  4. 按住鼠标左键完成绘图。
  5. 用鼠标右键清除图像。
  6. 在连续的鼠标位置之间绘制线段。
  7. 下面给出了一个正确且没有无偿悲观的实现。请注意以下事项:

    1. 图像是窗口小部件的用户属性。它可以设置,读取和跟踪。它很简单,例如将imageChanged连接到标签setPixmap,并有一个重复的画布显示。

    2. paintEvent强制执行前提条件&#34;正确大小的图像可以画出&#34;致电newImage

    3. 要更改QImage的尺寸,您必须创建新图像,使用QPainter::drawImage复制内容,然后将旧图像与新图像交换。

    4. 由于绘画工具的简单性,没有必要明确跟踪绘画/非绘画状态。

    5. 即使按下鼠标左键,也可以随时安全地清除图像。

    6. 小部件在被禁用时会忽略用户互动。

    7. setImage(std::move(someImage))是对不再需要someImage时的优化:它会保存副本。

    8. 相关的setter也是插槽 - 这使得小部件可以通过信号插槽连接与其他对象更加组合。

    9. 调整大小后没有必要明确安排更新:Qt已经这样做了。

    10. 不允许使用活动画家换出图像。

    11. 如果小部件的绘画正在进行中,则更改指示助手不会安排更新。这将是一次冗余更新。

    12. 画布始终完全自我绘制,并具有左上角对齐的内容。这些事实应在小部件的属性中表示,作为性能优化。

    13. 检查QImage::size()处理空图像 - 它们的大小也为空。

    14. 明显缺乏手动内存管理并非偶然,而是设计:代码中的任何地方都没有newdelete。在这种情况下,编译器可以为您完成所有操作。更喜欢将成员变量保持为值。例如。 QImage应按价值持有。它是一个价值类,没有必要通过new明确地分配它。事实上,这样做是过早的悲观。

    15. 自包含代码示例应该很小,最小,并且在一个文件中。在提问时你应该创建这样一个例子。

    16. // https://github.com/KubaO/stackoverflown/tree/master/questions/painting-app-48520925
      #include <QtWidgets>
      
      class PaintCanvas : public QWidget {
         Q_OBJECT
         Q_PROPERTY(QImage image READ image WRITE setImage NOTIFY imageChanged USER true)
         Q_PROPERTY(bool neverShrink READ neverShrink WRITE setNeverShrink)
         bool m_neverShrink = true;
         QImage m_image;
         QPoint m_lastPos;
         QPen m_pen{{Qt::red}, 3.0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin};
         void indicateChange() {
            emit imageChanged(m_image);
            if (!this->paintingActive()) update();
         }
         void newImage() {
            auto newSize = m_neverShrink ? size().expandedTo(m_image.size()) : size();
            if (newSize == m_image.size())
               return;
            QImage new_image{newSize, QImage::Format_ARGB32_Premultiplied};
            new_image.fill(Qt::white);
            QPainter p{&new_image};
            p.drawImage(0, 0, m_image);
            p.end();
            m_image.swap(new_image);
            indicateChange();
         }
         void paintEvent(QPaintEvent *) override {
            QPainter p{this};
            newImage(); // ensure that there's something to paint
            p.drawImage(0, 0, m_image);
         }
         void mousePressEvent(QMouseEvent *event) override {
            if (isEnabled() && event->buttons() & Qt::RightButton)
               clear();
            if (! isEnabled() || ! (event->buttons() & Qt::LeftButton))
               return;
            m_lastPos = event->pos();
            QPainter p{&m_image};
            p.setPen(m_pen);
            p.drawLine(m_lastPos, m_lastPos+QPoint{1,1});
            indicateChange();
         }
         void mouseMoveEvent(QMouseEvent *event) override {
            if (! isEnabled() || ! (event->buttons() & Qt::LeftButton))
               return;
            QPainter p{&m_image};
            p.setPen(m_pen);
            p.drawLine(m_lastPos, event->pos());
            m_lastPos = event->pos();
            indicateChange();
         }
      public:
         PaintCanvas(QWidget * parent = {}) : QWidget(parent) {
            setAttribute(Qt::WA_OpaquePaintEvent);
            setAttribute(Qt::WA_StaticContents);
         }
         Q_SIGNAL void imageChanged(const QImage &);
         QImage image() const { return m_image; }
         Q_SLOT void setImage(const QImage & image) {
            m_image = image;
            indicateChange();
         }
         void setImage(QImage && image) {
            m_image.swap(image);
            indicateChange();
         }
         bool neverShrink() const { return m_neverShrink; }
         void setNeverShrink(bool n) { m_neverShrink = n; }
         Q_SLOT void clear() {
            m_image = {};
            newImage();
         }
      };
      
      int main(int argc, char ** argv)
      {
         QApplication app(argc, argv);
         PaintCanvas canvas;
         canvas.show();
         return app.exec();
      }
      
      #include "main.moc"