【问题标题】:Qt Painter outside paintEvent - impossible - workaround?paintEvent 之外的 Qt Painter - 不可能 - 解决方法?
【发布时间】:2011-01-20 01:13:47
【问题描述】:

因此,Qt4 似乎不允许您在绘图事件之外的窗口上绘图。我有很多代码希望能够绘制橡皮筋线(用于特定的专有接口的通用绘图代码,然后我在给定的 UI 中实现)。我已经阅读了关于 pixmap 方法的内容,这将是很多工作,我认为这不是我真正想要的。

是否有一种解决方法可以让我做我想做的事?我只需要在屏幕上绘制 XOR 波段。

尝试了 WA_PaintOutsidePaintEvent 标志。然后我看到了说它在 Windows 上不起作用的位。

【问题讨论】:

    标签: c++ windows qt4


    【解决方案1】:

    在现代合成桌面中,窗口绘制需要由窗口管理器同步,以便可以将 alpha 混合和其他效果应用到正确的后台缓冲区 - 然后将其结果翻转到屏幕上以允许无撕裂的窗口动画。

    在此过程的带外调用绘画操作 - 虽然在底层平台上出于遗留原因支持 - 会破坏此过程并导致执行许多非常非最佳的代码路径。

    基本上,当您在窗口上进行绘画时:调用 invalidate 函数以尽快安排绘画,并在绘画事件期间绘画。

    【讨论】:

      【解决方案2】:

      只需绘制到QPixmap,然后将其复制到paintEvent 中的真实小部件。这是唯一的标准方式。您不应该尝试解决它。​​

      【讨论】:

        【解决方案3】:

        似乎如果您可以访问相关窗口的 Hwnd,您就可以在该表面上绘画。否则,我不确定。如果通过 pixmap 方法你的意思是这样的,我不认为这是一个糟糕的解决方案:

        m_composed_image = QImage(size, QImage::Format_ARGB32);
        m_composed_image.setDotsPerMeterX(dpm);
        m_composed_image.setDotsPerMeterY(dpm);
        m_composed_image.fill(Qt::transparent);
        
        //paint all image data onto new image
        QPainter painter(&m_composed_image);
        painter.drawImage(QPoint(0, 0), m_alignment_image); 
        

        【讨论】:

        • 不,pixmap 方法是先绘制到一个像素图上,然后再将其复制到绘制的窗口中。 HWND 的想法是我想过但希望避免的。如果可以的话,可能会崩溃并尝试找到一种更深的包裹方式;以“正确”的方式进行操作,并想出一些方法来区分软/硬刷新。
        【解决方案4】:

        正如其中一个答案所提到的,最好的方法是制作一个像素图缓冲区。绘画作品将在缓冲区中完成,完成后将安排repaint()。而paintEvent() 函数只是通过复制像素缓冲区来绘制小部件

        在用户输入值并按下按钮后,我试图在小部件区域上画一个圆圈。这是我的解决方案。将drawCircle() 插槽连接到clicked() 信号。

        class PaintHelper : public QWidget
        {
            Q_OBJECT
        private:
            QPixmap *buffer;
        
        public:
            explicit PaintHelper(QWidget *parent = 0) : QWidget(parent)
            {
                buffer=new QPixmap(350,250);// this is the fixe width of this widget so 
                buffer->fill(Qt::cyan);
            }
        
        signals:
        public slots:
            void drawCircle(int cx, int cy, int r){
        
        
                QPainter painter(buffer);
                painter.setBrush(QBrush(QColor(0,0,255)));
        
                // A part of mid-point algorithm to draw 1/8 pacrt of circle   
                int x1=0,y1=r;
                int p=1-r;
                for(int i=0;y1>=x1;i++){
                    painter.drawPoint(x1+cx,y1+cy);
                    x1++;
                    if(p>0){
                        p+=3+x1;
                    }
                    else{
                        y1--;
                        p+=2*x1-2*y1;
                        p++;
                    }
                }
                this->repaint();
            }
        
        
        
            // QWidget interface
        protected:
            void paintEvent(QPaintEvent *event)
            {
                QPainter painter(this);
                painter.drawPixmap(0,0,*buffer);
            }
        };
        

        【讨论】:

          猜你喜欢
          • 2020-07-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多