在 QML 中显示和刷新图像
Display and refresh an image in QML
我不明白如何使用QQuickPaintedItem
类(或者另一种方法?
我的程序目前正在使用 QImage
和 ImageProvider 显示它,它可以工作但随机崩溃,所以我想尝试另一种方法。
此外,每次传输新帧时都应刷新图像。
我从uchar
原始数据中获取信息,但我看不到如何从原始数据中绘制。
此外,新的原始数据大约以 60 fps 的速度出现,因此 QML 需要以这种速度刷新图像。
编辑:
代码的其他部分:
我的班级是:
class StreamPainter : public QQuickPaintedItem
{
Q_OBJECT
public:
StreamPainter(QQuickItem *p = 0):QQuickPaintedItem(p){}
~StreamPainter();
void paint(QPainter *painter){painter->drawImage(QPoint(0, 0), _streamImage);}
public slots:
void onImageAvailable(QImage image) {
_streamImage = image;
update();
private:
QImage _streamImage;
};
在主要:
对于无效的属性名称,这是由于导入了 StreamPainter 1.0,似乎它不喜欢这个名称,因为它被合并了,我已将其更改为 myModule,错误消失了。
qmlRegisterType<StreamPainter>("myModule", 1, 0, "StreamPainter");
创建对象和线程:
streamImage = new StreamPainter();
myPipeThread = new PipeThread(streamImage);
线程构造函数:
PipeThread::PipeThread(StreamPainter* spvideostr)
:QThread(),
_namedPipe(INVALID_HANDLE_VALUE),
_spvideostr(spvideostr),
_abort(false),
_rawData(NULL)
{
...
}
线程类,我添加了:
signals:
void imageAvailable(QImage image);
然后在我的线程中,我进行连接,同时我创建 QImage 并发出信号:
connect(this, SIGNAL(imageAvailable(QImage)), _spvideostr, SLOT(onImageAvailable(QImage)));
while(...)
QImage clImage(_rawData, IMG_WIDTH, IMG_HEIGHT, QImage::Format_Indexed8);
emit imageAvailable(clImage);
QML :
import QtQuick 2.0
import MyModule 1.0
StreamPainter {
width : 100
height : 100
就我而言,我在 QML 中使用组件中的函数刷新图像,如下所示:
Image {
id: imageLogo
cache: false
anchors.fill: parent
//anchors.leftMargin: 20
Layout.preferredWidth: Math.round(parent.width / 1.5)
Layout.preferredHeight: Math.round(parent.height * 2)
function reloadImage() {
var oldSource = source
source = ""
source = oldSource
}//function to refresh the source
}
然后我只在你想重新加载图像的地方调用这个函数
imageLogo.reloadImage()
这很简单,您所要做的就是在paint()
方法中绘制图像:
void paint(QPainter *painter) {
painter->drawImage(QPoint(0, 0), yourImage);
}
然后在每次更改时拨打update()
yourImage
。
不要绘制原始数据,使用正确的格式从中创建QImage
并绘制它。您可以使用静态方法QImage fromData(const uchar *data, int size, const char *format = Q_NULLPTR)
。由于QImage
是隐式共享对象,因此每次获取新数据时都可以有效地yourImage = QImage::fromData(...)
然后update()
。
编辑:
您应该在 QML 中创建对象。另外,看到如何使用线程,请记住 UI 元素只能从主线程访问。这意味着您无法执行此操作:
_spvideostr->setStreamImage(clImage);
_spvideostr->update();
当您从另一个线程访问 UI 对象时。相反,您应该使用带有排队连接的信号和插槽,通过该连接传递映像,然后从StreamPainter
插槽设置映像和调用update()
。
你不需要那个:
Q_PROPERTY(QImage streamImage READ streamImage WRITE setStreamImage NOTIFY streamImageChanged)
只能从该类访问此映像。所以你也不需要这些:
QImage streamImage();
void setStreamImage(QImage clImage);
signals:
void streamImageChanged(QImage Image);
您需要的是:
public slots:
void onImageAvaiable(QImage image) { ...set image and call update }
PipeThread
您需要一个信号void imageAvaiable(QImage)
,将imageAvaiable
连接到onImageAvaiable
并发出图像:
QImage clImage(_rawData, IMG_WIDTH, IMG_HEIGHT, QImage::Format_Indexed8);
emit imageAvaiable(clImage);
我通过将Image
的 source
属性绑定到我在任意查询字符串上附加的 url 来解决刷新 QML 中的图像,并且每次检索值时都使用自动递增计数器简单地更改图像位置附加部分中的值。
粗略地说,像这样(从 C 端):
QString imageURL()
{
static const QString QUERY_STRING_KEY( "?refresh=" );
static ushort imageRefreshCounter( 0 );
return imageUrl_ +
QUERY_STRING_KEY + QString::number( ++imageRefreshCounter );
}
当发出某些信号时,此功能将通过Q_PROPERTY隐式触发(例如 emit imageChanged();
),这将触发 QML 绑定刷新。
这样做,就不需要更改实际映像的名称,也无需在 QML 端进行清除和重置源属性的游戏。
注意:根据您希望如何在自己的项目中编写此内容,您可以选择进一步抽象它,使用文字 QUrl,并调用其 setQuery 方法。 我在这里用原始字符串展示这一点,只是为了让它更简单/直接一点。
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- OpenCV EqualizeHist()从彩色图像创建黑白图像
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 平均图像时图像损坏
- 在C++中使用GDAL可以将图像的像素坐标转换为lat,long吗
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- Vulkan验证层不断在VkQueuePresentKHR()上抛出图像布局错误
- 使用FFMPEG将RGB图像序列保存到.mp4时出现问题
- 将RGB图像保存为PPM格式
- 将图像添加到资源文件夹UWP C++
- 彩色图像的卤化物处理平均值
- C++射线示踪剂ppm表示没有足够的数据来显示图像
- 为什么PNG图像的stdout有时会在printf中刷新图像的一半
- GTK图像突然不会刷新任何错误或警告
- 调用Qpainter的方法绘制以刷新图像和更改颜色
- 在 QML 中显示和刷新图像
- 在 OnVScroll 上刷新图像
- 在c++gtk::drawinare:如何刷新图像
- 如何在win32中刷新图像显示白色,保持文字不变