0

我必须在透明 Qt 窗口的不同位置显示矩形。在显示窗口之前,我设置了新的矩形位置。有时旧位置会显示几毫秒。(例如 m_y_pos=100 而不是 m_y_pos=400)。似乎在显示窗口和更新窗口之间存在一种竞争条件。

我希望有人知道一个建议。

谢谢纸浆

示例代码:

#include <QApplication>
#include <QtWidgets/QMainWindow>
#include <QPaintEvent>
#include <QTimer>
#include <QDebug>
#include <QPainter>

class QtGuiApplication : public QMainWindow
{
  Q_OBJECT

public:
  int m_x_pos;
  int m_y_pos;
  QTimer* m_timer;

  QtGuiApplication(QWidget *parent = Q_NULLPTR) : QMainWindow(parent), m_x_pos(100), m_y_pos(100)
  {
    setGeometry(100, 100, 1000, 1000);

    //Make Window transparent
    setAttribute(Qt::WA_NoSystemBackground, true);
    setAttribute(Qt::WA_TranslucentBackground);
    setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus);

    m_timer = new QTimer(this);
    m_timer->setInterval(500);
    m_timer->start();
    connect(m_timer, &QTimer::timeout, this, &QtGuiApplication::Tick);
  }

  private slots:

  //toggle visibility of the window to show the effect
  void Tick()
  {
    if (isVisible())
    {
      hide();
    }
    else
    {
      //Set new position before showing the window
      m_y_pos = m_y_pos == 100 ? 400 : 100;
      show();
    }
  }

  //Paint rectangles at different positions
  void paintEvent(QPaintEvent* event)
  {
    QPainter painter(this);

    painter.setBrush(Qt::red);
    painter.setPen(Qt::black);

    for (int i = 0; i < event->rect().width(); i += 50)
    {
      painter.drawRect(m_x_pos + i, m_y_pos, 30, 30);
    }
  }

};

int main(int argc, char *argv[])
{
  QApplication a(argc, argv);
  QtGuiApplication w;
  w.show();
  return a.exec();
}
4

1 回答 1

0

update()改变职位后,您缺乏对的电话。通常,这应该被考虑到一个setPos方法中。

一旦你这样做了,hide()andshow()就不再需要了:每次setPos调用都会根据需要更新小部件。

您应该从满足您需求的最基本的类派生:QWidget. QMainWindow毕竟,您没有使用 的任何功能。

// https://github.com/KubaO/stackoverflown/tree/master/questions/rect-paint-42194052
#include <QtWidgets>

class Window : public QWidget
{
   QPointF m_pos{100, 100};
   void paintEvent(QPaintEvent* event) override
   {
      QPainter painter(this);
      painter.setBrush(Qt::red);
      painter.setPen(Qt::black);
      for (int i = 0; i < event->rect().width(); i += 50)
         painter.drawRect(QRectF(m_pos.x() + i, m_pos.y(), 30, 30));
   }
public:
   Window(QWidget *parent = nullptr) : QWidget(parent)
   {
      setAttribute(Qt::WA_NoSystemBackground, true);
      setAttribute(Qt::WA_TranslucentBackground);
      setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint
                     | Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus);
   }
   void setPos(const QPointF & pos) {
      m_pos = pos;
      update();
   }
};

int main(int argc, char ** argv) {
   QApplication app{argc, argv};
   Window w;
   QTimer timer;
   QObject::connect(&timer, &QTimer::timeout, [&w]{
      static bool toggle{};
      if (!w.isVisible()) {
         toggle = !toggle;
         if (toggle)
            w.setPos({200, 200});
         else
            w.setPos({100, 100});
      };
      w.setVisible(!w.isVisible());
   });
   timer.start(500);
   w.resize(1000, 500);
   return app.exec();
}
于 2017-02-13T15:46:58.390 回答