- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个应用程序需要以指定的帧速率逐个像素地绘制(模拟旧机器)。需要注意的是,主机引擎在后台线程中运行,以确保 UI 在模拟期间保持响应和可用。
目前,我正在尝试使用这样的东西:
class QVideo : public QWidget {
public:
QVideo(QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f), screen_image_(256, 240, QImage::Format_RGB32) {
}
void draw_frame(void *data) {
// render data into screen_image_
}
void start_frame() {
// do any pre-rendering prep work that needs to be done before
// each frame
}
void end_frame() {
update(); // force a paint event
}
void paintEvent(QPaintEvent *) {
QPainter p(this);
p.drawImage(rect(), screen_image_, screen_image_.rect());
}
QImage screen_image_;
};
这主要是有效的,而且令人惊讶的是不是很慢。但是,有一个问题。更新函数安排一个paintEvent
,它可能不会马上发生。事实上,根据 Qt 文档,一堆 paintEvent
可能会“合并”。
我看到的负面影响是,在模拟几分钟后,屏幕停止更新(尽管模拟仍在运行,但图像似乎卡住了),直到我执行一些强制屏幕更新的操作,例如打开和关闭窗口的最大化。
我曾尝试使用 QTimer
和其他类似机制来实现在 GUI 线程中进行渲染的效果,以便我可以强制立即更新,但这导致了无法接受的性能问题。
有没有更好的方法以固定的间隔不断地将像素绘制到小部件上。首选纯 Qt 解决方案。
编辑自some people选择有一种态度而不是阅读整个问题,我会澄清这个问题。我不能使用 QWidget::repaint
因为它有一个限制,它必须从与事件循环相同的线程调用。否则,不会发生任何更新,而是会收到如下 qDebug 消息:
QPixmap: It is not safe to use pixmaps outside the GUI thread
QPixmap: It is not safe to use pixmaps outside the GUI thread
QWidget::repaint: Recursive repaint detected
QPainter::begin: A paint device can only be painted by one painter at a time.
QWidget::repaint: It is dangerous to leave painters active on a widget outside of the PaintEvent
QWidget::repaint: It is dangerous to leave painters active on a widget outside of the PaintEvent
编辑:为了演示这个问题,我创建了这个简单的示例代码:
QVideo.h
#include <QWidget>
#include <QPainter>
class QVideo : public QWidget {
Q_OBJECT;
public:
QVideo(QWidget *parent = 0, Qt::WindowFlags f = 0) : QWidget(parent, f), screen_image_(256, 240, QImage::Format_RGB32) {
}
void draw_frame(void *data) {
// render data into screen_image_
// I am using fill here, but in the real thing I am rendering
// on a pixel by pixel basis
screen_image_.fill(rand());
}
void start_frame() {
// do any pre-rendering prep work that needs to be done before
// each frame
}
void end_frame() {
//update(); // force a paint event
repaint();
}
void paintEvent(QPaintEvent *) {
QPainter p(this);
p.drawImage(rect(), screen_image_, screen_image_.rect());
}
QImage screen_image_;
};
主.cc:
#include <QApplication>
#include <QThread>
#include <cstdio>
#include "QVideo.h"
struct Thread : public QThread {
Thread(QVideo *v) : v_(v) {
}
void run() {
while(1) {
v_->start_frame();
v_->draw_frame(0); // contents doesn't matter for this example
v_->end_frame();
QThread::sleep(1);
}
}
QVideo *v_;
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QVideo w;
w.show();
Thread t(&w);
t.start();
return app.exec();
}
我绝对愿意探索不使用临时 QImage
进行渲染的选项。它只是 Qt
中唯一一个似乎具有直接像素写入接口(interface)的类。
最佳答案
尝试从线程向调用 repaint() 的事件循环小部件中的槽发出信号,然后立即执行。我正在我的绘图程序中做这样的事情,它在一个线程中执行主要计算,然后告诉小部件什么时候该重新绘制()数据。
关于c++ - 将基于像素的图形绘制到 QWidget,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4403019/
我有一个关于 c++ 中的 qt 的问题 头文件: #ifndef TIMER_H #define TIMER_H #include #include #include #include cl
我有以下代码: import os from functools import partial import numpy as np from PyQt5 import QtCore, QtWidge
我有一个 QWidget B,它包含在 QWidget A 中。QWidget A 有一个 QLabel。我在 QWidget B 中有一些数据,我想将其设置为 QLabel 的值。这种事情怎么办?
为了解释这种情况,我有一个 QMainWindow,里面有很多东西。我的目标是制作某种通知,显示在该窗口的右下角。 通知小部件必须位于所有其他小部件之上。 到目前为止,我已经创建了从 QWidget
这个问题对我来说可能是缺乏对 C++ 的理解,因为我为我的问题考虑过的所有可能性似乎都无法说明为什么会发生这种情况。感谢反馈。 我正在使用表单设计器创建一个包含表格的表单类。我正在尝试用辅助类中生成的
我选择使用 Qt 来管理我正在处理的项目的 GUI。 在找到如何在我的 QWidget 底部应用图片后,我注意到它对添加到其中的所有组件都有影响。 无论通过 setStyleSheet 方法或什至使用
我有一个带有两个小部件的主窗口,buttonsWidget 和 infoWidget。我试图在单击 buttonsWidget 中的按钮后隐藏 infoWidget(并最终显示不同的小部件)。 我试过
虽然 Qt's docs表明这两个功能是不同的(第一个不包括框架)无论我选择什么小部件 - 包括我的应用程序的主窗口 - someWidget->frameGeometry().height()始终返
这是包含一系列小部件的 QFormLayout 的屏幕截图。请注意,顶部和底部输入小部件未与中间两行水平对齐。另请注意,左侧的标签未与中间两行垂直对齐。 不同之处在于顶部和底部小部件是普通的 QLin
我有几个小部件,比如 QLineEdit m_namePoiFilter; QLineEdit m_ID_MSSIPoiFilter; 我想将它们添加到 qwi
我创建了一个非常简单的 QWidget 子类,如下所示: class WorldView : public QWidget { Q_OBJECT public: explicit Wo
我在屏幕上有很多固定的 qwidgets,还有很多其他的 widgets 我可以在屏幕上拖动。当一个小部件被拖动到固定小部件之上时,固定小部件需要执行一些代码。我无法弄清楚静止对象如何知道它上面有一个
我正在使用 Qt 设计器 4.8.7,从它开始。我创建了一个 MainWindow ,我想在其中加载布局。 我有一个小部件,由 Qt 设计器使用 pyuic4 生成。 我加载我的小部件正在做 self
我正在尝试使 QWidget 粘在屏幕右边框上,并在左侧显示/隐藏另一个 QWidget。我们的目标是在决赛中实现类似的目标: ---------------------------------- |
完全使用 QT Designer。我创建了一个 QWidget 来封装一组控件。我现在想在 QMainWindow 表单中多次使用此 QWidget。 如何仅使用 QT Designer 将我的 QW
我有一组出现在不同地方的小弹出窗口小部件,但每次只出现一个。对于简单的功能,new-to-show 和 delete-to-hide 没问题,并且按预期工作,但当它们开始处理自己的数据时,我可以看到内
我有一些 QWidget 类,它的 ui 文件与 QMainWindow ui 文件是分开的。 如何将粘附到 QMainWindow 的当前 QWidet 添加或替换为来自同一 QMainWindow
我正在使用基于 QWidget 的 PyQt 开发应用程序。我将整个应用程序放在一个类中(名为“示例”)。在这个应用程序中,我有一个按钮可以调用我在 QtDesigner 上设计的另一个 QWidge
在运行时尝试向 QWidget 添加按钮时,我遇到了一个奇怪的问题。我有一个带有 QTabWidget 的窗口,它有 2 个选项卡。当我按下窗口上的按钮时,它会在第一个选项卡上生成一组复选框。 问题是
我正在尝试运行一个简单的 Qt 程序,这样做时,我得到一个控制台窗口,提示:QWidget: Cannot create a QWidget when no GUI is being used,第二行
我是一名优秀的程序员,十分优秀!