通过按钮单击触发带有参数的 QQuickImageProvider::requestImage()
Posted
技术标签:
【中文标题】通过按钮单击触发带有参数的 QQuickImageProvider::requestImage()【英文标题】:Trigger QQuickImageProvider::requestImage() with parameter via button click 【发布时间】:2018-10-22 13:52:58 【问题描述】:我有一个使用QQuickImageProvider
显示图像的 QQuickControls 2 应用程序。有时我只是想显示一个未经编辑的图像,所以我只是像这样实现我的 QML:
Image
id: image
fillMode: Image.PreserveAspectFit
source: "image://provider/foo/bar/placeholder.jpg"
其他时候我会想显示图像的编辑版本。我如何告诉QQuickImageProvider::requestImage()
我想展示一个编辑过的版本?
QImage ImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
// Somehow determine we need to show an editted version of the image
if (showEdited)
// maybe pass query parameters to the id?
// for eg 'image://provider/foo/bar/i.jpg?edit=true'
// Then I parse the id string for this query parameter?
cv::Mat src = cv::imread(id.toStdString());
// ... perform some image processing to the image
QImage img = convertMatToQImage(src);
if (size)
*size = QSize(img.width(), img.height());
return img;
else
QImage img(id);
if (size)
*size = QSize(img.width(), img.height());
return img;
显示编辑图像的触发器是通过单击按钮:
Button
id: processBtn
text: qsTr("Process")
onClicked:
// Somehow call QQuickImageProvider::requestImage() and specify we are editting it?
// Maybe...
// image.source = image.source + "?edit=true"
【问题讨论】:
传递id
,例如image
或image-edited
并在requestImage()
中解析它,或者,这是正确的,创建2 个图像提供程序并使用你需要的。
【参考方案1】:
我可以传递图像的 url,并使用 QUrl 类来获取 edit=true
,如下所示:
QImage ImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize)
Q_UNUSED(requestedSize)
QUrl url(id);
bool showEdited = url.query() == "edit=true";
if (showEdited)
cv::Mat src = cv::imread(url.toLocalFile().toStdString());
///begin process
cv::GaussianBlur(src, src, cv::Size(3,3), 0, 0, cv::BORDER_DEFAULT );
cv::Mat grad_x, grad_y;
cv::Mat abs_grad_x, abs_grad_y, src_gray, grad;
int scale = 1;
int delta = 0;
int ddepth = CV_16S;
cv::cvtColor( src, src_gray, CV_BGR2GRAY );
/// Gradient X
cv::Sobel( src_gray, grad_x, ddepth, 1, 0, 3, scale, delta, cv::BORDER_DEFAULT );
/// Gradient Y
cv::Sobel( src_gray, grad_y, ddepth, 0, 1, 3, scale, delta, cv::BORDER_DEFAULT );
convertScaleAbs( grad_x, abs_grad_x );
convertScaleAbs( grad_y, abs_grad_y );
addWeighted( abs_grad_x, 0.5, abs_grad_y, 0.5, 0, grad );
///end process
QImage img = convertMatToQImage(grad);
if (size)
*size = QSize(img.width(), img.height());
return img;
else
QImage img(url.toLocalFile());
if (size)
*size = QSize(img.width(), img.height());
return img;
main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.11
import QtQuick.Dialogs 1.0
Window
visible: true
width: 640
height: 480
title: qsTr("Hello World")
property string path: ""
onPathChanged: image.source = path == "" ? "": "image://provider/"+ path
ColumnLayout
anchors.fill: parent
Image
id: image
Layout.preferredWidth: parent.width
Layout.preferredHeight: parent.height * 0.8
fillMode: Image.PreserveAspectFit
Pane
id: pane
Layout.fillWidth: true
RowLayout
width: parent.width
Button
id: selectBtn
text: qsTr("Select")
Layout.alignment: Qt.AlignHCenter
onClicked: fileDialog.open();
Button
id: processBtn
text: qsTr("Process")
Layout.alignment: Qt.AlignHCenter
onClicked: if(path != "") image.source = "image://provider/"+ path + "?edit=true"
FileDialog
id: fileDialog
title: "Please choose a file"
folder: shortcuts.home
nameFilters: [ "Image files (*.jpg *.png)", "All files (*)" ]
onAccepted: path = fileDialog.fileUrl
原文:
流程:
完整的例子可以在this link.找到
【讨论】:
【参考方案2】:使用id
而不使用类似的扩展名:
Button
property bool edit: false
onClicked:
image.source = "image:://provider/foo/path" + (edit ? placeholder-edit : placeholder )
但是您可以在没有图像提供程序的情况下使用自定义属性实现 QQuickPaintedItem
【讨论】:
以上是关于通过按钮单击触发带有参数的 QQuickImageProvider::requestImage()的主要内容,如果未能解决你的问题,请参考以下文章
IOS Toolbarbutton项目不触发带有滚动条的动作