gpt4 book ai didi

c++ - Qml 图像不会在源更改和信号接收时刷新

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:14:06 28 4
gpt4 key购买 nike

我在 Qt Creator 中创建了“fruit_swap”项目 bt 选择 -- Application -> Qt Quick Application -> Qt 5.5。在 fruit_swap 中,'main()' 函数调用 forkSwapper(),它 fork 一个进程,每秒交换一次水果图像(苹果 <--> 梨)。

交换是在 setImageURL() 方法内部完成的,该方法还为 qml 发出“imageURLChanged”信号。从输出(如下图底部所示)可以看出,信号已传送到 qml 端。

我期待 qml 图像交换。然而,它没有。显示的第一张图片(“梨”)一动不动。我做错了什么?欢迎任何建议。我在下面上传了每一个源代码。

enter image description here

fruit_swap.pro

/* Qt Creator生成*/

TEMPLATE = app

QT += qml quick
CONFIG += c++11

SOURCES += main.cpp \
imageitem.cpp

RESOURCES += qml.qrc

# Additional import path used to resolve QML modules in Qt Creator's code model
QML_IMPORT_PATH =

# Default rules for deployment.
include(deployment.pri)

HEADERS += \
imageitem.h

DISTFILES += \
FruitFrame.qml

图片项.h

/* https://quickgit.kde.org/?p=scratch%2Fsune%2Fimageitem.git */

#include <QQuickPaintedItem>
/**
* @brief QQuickItem to show images/pixmaps/colors in a QML item
*
* As opposed to the Image from plain qml, this works on
* QImages, QPixmaps and QColors
*/
class ImageItem : public QQuickPaintedItem
{
// Q_PROPERTY(QVariant imageData READ imageData() WRITE setImageData
// NOTIFY imageDataChanged)
Q_OBJECT
Q_PROPERTY(QVariant imageURL READ imageURL() WRITE setImageURL
NOTIFY imageURLChanged)
public:
explicit ImageItem(QQuickItem *parent = 0);
/**
* \reimpl
*/
Q_INVOKABLE void paint(QPainter* painter) Q_DECL_OVERRIDE;
/**
* @brief image data u-ed by this item
* @return a QVariant wrapping the data
*/
QVariant imageData() const;
/**
* @brief Sets the image data
* @param newData
*/
void setImageData(const QVariant& newData);

QVariant imageURL() const;
/**
* @brief Sets the image data
* @param newData
*/
void setImageURL(const QVariant& fileName);
Q_SIGNALS:
/**
* @brief imageChanged
*/
void imageDataChanged();
void imageURLChanged();

private:
enum Type {
Unknown,
Pixmap,
Image,
Color
};
Type m_type;
QVariant m_imageData;
QVariant m_imageURL;
QRectF scaledRect(const QRect& sourceRect) const;
};
#endif // IMAGEITEM_H

图像项.cpp

/* https://quickgit.kde.org/?p=scratch%2Fsune%2Fimageitem.git */

#include "imageitem.h"
#include <QPainter>
#include <qobjectdefs.h>

ImageItem::ImageItem(QQuickItem *parent) :
QQuickPaintedItem(parent)
{
m_imageURL = QUrl::fromLocalFile(QString("apple.jpg"));
}

void ImageItem::paint(QPainter* painter)
{
switch(m_type) {
case Unknown: {
return;
}
case Image: {
QImage image = m_imageData.value<QImage>();
painter->drawImage(scaledRect(image.rect()), image);
return;
}
case Pixmap: {
QPixmap pixmap = m_imageData.value<QPixmap>();
painter->drawPixmap(scaledRect(pixmap.rect()).toRect(), pixmap);
return;
}
case Color: {
QColor color = m_imageData.value<QColor>();
painter->fillRect(contentsBoundingRect(),color);
return;
}
}
}

QVariant ImageItem::imageData() const
{
return m_imageData;
}

QVariant ImageItem::imageURL() const
{
return m_imageURL;
}

void ImageItem::setImageURL(const QVariant &fileName)
{
m_imageURL = QUrl::fromLocalFile(fileName.value<QString>());
if (m_imageURL.canConvert<QUrl>()) {
QUrl url = m_imageURL.value<QUrl>();
if (!url.isEmpty() && url.isValid()
&& url.isLocalFile())
{
qDebug() << "URL is valid";
} else {
qDebug() << "URL is INvalid";
}
} else {
qDebug() << "URL is INvalid";
}
emit imageURLChanged();
}

void ImageItem::setImageData(const QVariant& newData)
{
switch(newData.userType()) {
case QMetaType::QPixmap: {
m_type = Pixmap;
break;
}
case QMetaType::QImage: {
m_type = Image;
break;
}
case QMetaType::QColor: {
m_type = Color;
break;
}
default: {
m_type = Unknown;
break;
}
}
m_imageData = newData;
emit imageDataChanged();
}

QRectF ImageItem::scaledRect(const QRect& sourceRect) const
{
QRectF targetRect = contentsBoundingRect();

QSizeF scaledSize;

double widthScale = targetRect.width() / sourceRect.width();
double heightScale = targetRect.height() / sourceRect.height();
if(widthScale < heightScale) {
scaledSize.setHeight(sourceRect.height() * widthScale);
scaledSize.setWidth(sourceRect.width() *widthScale);
} else {
scaledSize.setHeight(sourceRect.height() * heightScale);
scaledSize.setWidth(sourceRect.width() *heightScale);
}

QRectF result = QRectF(targetRect.left() + targetRect.width() /2 - scaledSize.width() /2,
targetRect.top() + targetRect.height()/2 - scaledSize.height()/2,
scaledSize.width(),scaledSize.height());
// QRectF result(QPointF(0,0),scaledSize);
qDebug() << result << targetRect << sourceRect << widthScale << heightScale ;
return result;
}

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QImage>
#include <unistd.h>

#include "imageitem.h"

void forkSwapper(ImageItem * fImage);

int main(int argc, char *argv[])
{
qmlRegisterType<ImageItem>("ImageItem",1,0,"ImageItem");

QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
ImageItem *fImage = new ImageItem();

fImage->setImageURL("fruit.jpg");

engine.rootContext()->setContextProperty("cpp_imageURL", fImage);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

forkSwapper(fImage);

return app.exec();
}

void forkSwapper(ImageItem * fImage) {

int pid = fork();

if (pid == 0) {
int i = 0;
while (true) {
if (i++ % 2 == 0)
fImage->setImageURL("apple.jpg");
//std::system("cp apple.jpg fruit.jpg");
else
fImage->setImageURL("pear.jpg");
//std::system("cp pear.jpg fruit.jpg");

qDebug() << "fruit image changed";
sleep(1);
}
_exit (EXIT_FAILURE);
} else {
qDebug() << "swapper forked, PID:" << pid;
}
}

水果框架.qml

import QtQuick 2.5
import ImageItem 1.0

Rectangle {
property alias mouseArea: mouseArea

width: 360
height: 360

MouseArea {
id: mouseArea
anchors.fill: parent

Connections {
target: cpp_imageURL
onImageURLChanged: {
fruit_image.update();
// fruit_image.source = cpp_imageURL.imageURL;
console.log("image UURL-" + cpp_imageURL.imageURL);
}
}

Image {
id: fruit_image
x: 39
y: 94
width: 274
height: 204
source: cpp_imageURL.imageURL
cache: false
}
}

Text {
anchors.centerIn: parent
text: "Hello World"
anchors.verticalCenterOffset: -137
anchors.horizontalCenterOffset: -104
}
}

主.qml

import QtQuick 2.5
import QtQuick.Window 2.2
import ImageItem 1.0

Window {
visible: true

width: 360
height: 460

FruitFrame {
anchors.fill: parent
mouseArea.onClicked: {
Qt.quit();
}
}
}

应用输出

Starting /home/jbpark03/wem/fruit_swap/build/fruit_swap...
QML debugging is enabled. Only use this in a safe environment.
URL is valid
URL is valid
qml: image UURL-file:apple.jpg
fruit image changed
swapper forked, PID: 3078
URL is valid
qml: image UURL-file:pear.jpg
fruit image changed
URL is valid
qml: image UURL-file:apple.jpg
fruit image changed
URL is valid
qml: image UURL-file:pear.jpg
fruit image changed
URL is valid
qml: image UURL-file:apple.jpg

结束。

最佳答案

代码运行良好。我认为问题在于您正在阻止 Qt 应用程序,因为您正在使用 sleep

事实上,您看到图像 pear.jpg 因为它是 fruit.jpg 之后和任何 sleep 之前显示的第一张图像。

例如,如果您使用 QTimerQThread,您将检查图像是否已正确更新。

例子:

mytimer.h

#ifndef MYTIMER_H
#define MYTIMER_H

#include <QObject>
#include <QTimer>
#include "imageitem.h"

class MyTimer : public QObject
{
Q_OBJECT
public:
explicit MyTimer(ImageItem * fImage, QObject *parent = 0);

private:
QTimer *timer;
ImageItem *myImage;

signals:

public slots:
void update();
};

#endif // MYTIMER_H

mytimer.cpp

#include <QDebug>
#include <QTest>
#include "mytimer.h"

MyTimer::MyTimer(ImageItem * fImage, QObject *parent) : QObject(parent)
{
myImage = fImage;
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(1000);
}

void MyTimer::update()
{
myImage->setImageURL(":pear.jpg");

QTest::qWait(250);

myImage->setImageURL(":apple.jpg");
}

有了这个计时器,我们将每 1 秒更改一次图像。现在,在我们的 main.cpp 中:

#include "mytimer.h"

int main(int argc, char *argv[])
{
qmlRegisterType<ImageItem>("ImageItem",1,0,"ImageItem");

QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
ImageItem *fImage = new ImageItem();
MyTimer *timer = new MyTimer(fImage);

fImage->setImageURL(":fruit.jpg");

engine.rootContext()->setContextProperty("cpp_imageURL", fImage);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

return app.exec();
}

关于c++ - Qml 图像不会在源更改和信号接收时刷新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36222586/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com