Qt QWidget/QPainter show()和#x2B;paintEvent()->;在旧位置显示矩形
我必须在透明的Qt窗口上显示不同位置的矩形。 在显示窗口之前,我设置了新的矩形位置。有时,旧位置会显示几毫秒。(例如,m_y_pos=100而不是m_y_pos=400)。在显示窗口和更新窗口之间似乎存在某种竞争条件 我希望有人知道一个建议 谢谢纸浆 示例代码:Qt QWidget/QPainter show()和#x2B;paintEvent()->;在旧位置显示矩形,qt,transparent,qwidget,paintevent,Qt,Transparent,Qwidget,Paintevent,我必须在透明的Qt窗口上显示不同位置的矩形。 在显示窗口之前,我设置了新的矩形位置。有时,旧位置会显示几毫秒。(例如,m_y_pos=100而不是m_y_pos=400)。在显示窗口和更新窗口之间似乎存在某种竞争条件 我希望有人知道一个建议 谢谢纸浆 示例代码: #include <QApplication> #include <QtWidgets/QMainWindow> #include <QPaintEvent> #include <QTimer&
#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();
}
#包括
#包括
#包括
#包括
#包括
#包括
类QTGUI应用程序:公共QMainWindow
{
Q_对象
公众:
int m_x_pos;
国际货币基金组织;
QTimer*m_定时器;
qtgui应用程序(QWidget*parent=Q_NULLPTR):QMainWindow(parent)、m_x_pos(100)、m_y_pos(100)
{
集合几何(10010010001000);
//使窗户透明
setAttribute(Qt::WA_NoSystemBackground,true);
setAttribute(Qt::WA_半透明背景);
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint | Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus);
m_timer=新的QTimer(此);
m_定时器->设置间隔(500);
m_定时器->启动();
连接(m_定时器,&QTimer::timeout,this,&QtGuiApplication::Tick);
}
专用插槽:
//切换窗口的可见性以显示效果
空勾()
{
if(isVisible())
{
隐藏();
}
其他的
{
//在显示窗口之前设置新位置
m_y_pos=m_y_pos==100?400:100;
show();
}
}
//在不同位置绘制矩形
无效paintEvent(QPaintEvent*事件)
{
油漆工(本);
画家。挫折(Qt::红色);
画师:设置笔(Qt::黑色);
对于(int i=0;irect().width();i+=50)
{
painter.drawRect(m_x_pos+i,m_y_pos,30,30);
}
}
};
int main(int argc,char*argv[])
{
质量保证申请a(argc、argv);
qtguiw;
w、 show();
返回a.exec();
}
更改位置后,您缺少对update()
的调用。通常,这应该被分解为setPos
方法
一旦这样做,就不再需要hide()
和show()
:每次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();
}
//https://github.com/KubaO/stackoverflown/tree/master/questions/rect-paint-42194052
#包括
类窗口:公共QWidget
{
QPointF m_pos{100,100};
无效paintEvent(QPaintEvent*事件)覆盖
{
油漆工(本);
画家。挫折(Qt::红色);
画师:设置笔(Qt::黑色);
对于(int i=0;irect().width();i+=50)
painter.drawRect(QRectF(m_pos.x()+i,m_pos.y(),30,30));
}
公众:
窗口(QWidget*parent=nullptr):QWidget(parent)
{
setAttribute(Qt::WA_NoSystemBackground,true);
setAttribute(Qt::WA_半透明背景);
setWindowFlags(Qt::Tool | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint)
|Qt::WindowTransparentForInput | Qt::WindowDoesNotAcceptFocus);
}
无效设置位置(常量QPointF和位置){
m_pos=pos;
更新();
}
};
int main(int argc,字符**argv){
QApplication app{argc,argv};
窗口w;
定时器;
QObject::connect(&timer,&QTimer::timeout,[&w]{
静态布尔开关{};
如果(!w.isVisible()){
切换=!切换;
如果(切换)
w、 setPos({200200});
其他的
w、 setPos({100100});
};
w、 setVisible(!w.isVisible());
});
定时器启动(500);
w、 调整大小(1000500);
返回app.exec();
}
我无法在此处重现您的问题,但一般来说,只要参数改变了小部件的外观,您就应该通过调用update()
通知喷漆系统您的小部件需要更新。(即,在您的情况下,直接在Tick()
中设置m_y_pos
后)行为只能在启用Aero的Windows 7下复制。感谢您的解决方案。我对它进行了测试:效果仍然存在(Windows 7,启用了Aero),因为如果窗口不可见,update()将无效。目前,我使用了一种变通方法:我移动屏幕的窗口,而不是隐藏它。(是的,很糟糕…)那就是Qt错误。