How to use qt-component OpacityMask - qt

There is a question How to hide an image using transparent rectangle in QML?
The accepted answer is to use OpacityMask.
I created a qml file follow this answer, but didn't get the expected result.
Is there anything wrong in my codes?
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtGraphicalEffects 1.0
ApplicationWindow {
visible: true
width: 1280
height: 800
title: qsTr("Hello World")
Rectangle {
id: background
anchors.fill: parent
color: "black"
}
Image
{
id:underlyingImage
width: 1204
height: 682
fillMode: Image.PreserveAspectCrop
layer.enabled: true
layer.effect: OpacityMask {
maskSource: hiding_rect
}
source:"qrc:/timg.jpg"
}
Rectangle
{
id:hiding_rect
width: underlyingImage.width/2
height: underlyingImage.height/2
color: "yellow"
}
}
the result picture

I'm not familiar with the approach suggested in the other question.
However, following the approach suggested in the documentation (http://doc.qt.io/qt-5/qml-qtgraphicaleffects-opacitymask.html), this works:
Window {
visible: true
width: 1280
height: 800
title: qsTr("Hello World")
Rectangle {
id: background
anchors.fill: parent
color: "black"
}
Image
{
anchors.centerIn: parent
id:underlyingImage
width: 1204
height: 682
fillMode: Image.PreserveAspectCrop
source:"file:///tmp/timg.jpg"
visible: false
}
Item {
id:hiding_rect
anchors.fill: underlyingImage
visible: false
Rectangle
{
anchors.left: parent.left
anchors.top: parent.top
width: underlyingImage.width/2
height: underlyingImage.height/2
color: Qt.rgba(1,1,1,1)
z: underlyingImage.z + 1
}
}
OpacityMask {
anchors.fill: underlyingImage
source: underlyingImage
maskSource: hiding_rect
}
}

Related

How to load and display QML file

I have two QML pages main.qml and Kos.qml,
what i want is when a button in main.qml clicked it load Kos.qml in the screen.
i did try using loader, but it is not working
import QtQuick 2.5
import QtQuick.Controls 2.5
ApplicationWindow {
id: applicationWindow
width: 640
height: 480
color: "#fc4343"
title: qsTr("Tabs")
visible: true
// HALAMAN UTAMA
Page {
anchors.centerIn: parent
anchors.fill: parent
id: page
enabled: true
Loader{
id: kos
active: true
anchors.fill: parent
}
Button {
id: button
x: 198
width: 87
height: 30
text: qsTr("Search")
font.bold: true
anchors.top: borderImage.bottom
anchors.topMargin: 198
anchors.right: toolSeparator.left
anchors.rightMargin: 28
MouseArea{
anchors.fill: parent
onClicked:{
kos.source = "Kos.qml";
}
}
background: Rectangle {
id: background
color: "#ef3644"
}
contentItem: Text {
id: textItem
font: control.font
opacity: enabled ? 1.0 : 0.3
color: "white"
text: "Search"
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
elide: Text.ElideRight
}
}
}
Kos.qml i use PageBackground as a background
import QtQuick 2.4
PageBackground {
id: kos
width: 640
height: 480
Text {
id: element
x: 6
y: 20
width: 24
height: 32
color: "#ffffff"
text: qsTr("<")
font.strikeout: false
styleColor: "#ffffff"
font.underline: false
font.italic: false
font.bold: true
font.pixelSize: 25
MouseArea {
id: mouseArea
anchors.rightMargin: 0
anchors.bottomMargin: 0
anchors.leftMargin: 0
anchors.topMargin: 0
anchors.fill: parent
}
}
}
did i messed up somewhere?
I tried to run your code. Since I am not aware of what your PageBackground is, I changed that to Rectangle. That works for me. Try to start from the minimal code then add your styles and functions on top of it. Try with below minimal code. Keep both main.qml & Kos.qml in the same directory and ensure both files added to qml resources.
main.qml
import QtQuick 2.9
import QtQuick.Controls 2.2
ApplicationWindow {
id: applicationWindow
width: 640
height: 480
visible: true
Text {
anchors.centerIn: parent
text: "App window"
}
Loader {
id: loaderId
anchors.fill: parent
source: ""
}
Button {
text: "click me!!"
width: parent.width
anchors.bottom: parent.bottom
onClicked: {
if(loaderId.source == "")
loaderId.source = "Kos.qml"
else
loaderId.source = ""
}
}
}
Kos.qml
import QtQuick 2.9
Rectangle {
id: kos
width: 640
height: 480
color: "grey"
Text {
anchors.centerIn: parent
text: "<b>Loaded Item</b>"
color: "white"
}
}

How can I call a custom signal from a QML Component?

Is there a way to call a signal from a mouseArea included in a component which is loaded somewhere else?
onClicked in the example below is not entered when i click on the rectangle.
The structure needs to remain as defined. To be able to define a qml component that applies a shadow to any source
Here is the code:
Window{
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Item
{
id: mainRectangle
anchors.centerIn: parent
width: loaderId.width + 60
height: loaderId.height + 60
Rectangle {
id: rect2
anchors.right: mainRectangle.right
anchors.top: mainRectangle.top
anchors.rightMargin: -30
anchors.topMargin: -30
width: 100
height: 100
color: "red"
opacity: 0.5
}
Loader {
id: loaderId
anchors.centerIn: parent
sourceComponent: component
active:true
}
visible: false
}
ShaderEffectSource {
id: shader
anchors.fill: mainRectangle
anchors.margins: -30
sourceItem: mainRectangle
opacity: 0.5
visible: true
}
Component {
id: component
Rectangle {
id: rect
width: 100
height: 100
color: "black"
MouseArea {
anchors.fill: parent
onClicked: {
console.log("Clicked!")
// call a signal from here
}
}
}
}
}
In the end the should show what it does now and the mouseArea should work.
onClicked in the example below is not entered when i click on the rectangle.
mainRectangle is not visible, and items that aren't visible don't get input events. Since the MouseArea is a child of mainRectangle, it won't get events either.
In the end the should show what it does now and the mouseArea should work.
Instead of hiding the source item and using ShaderEffectSource, you can set the opacity directly on mainRectangle and use item layers (the link has a similar example) to ensure that there is no overlap due to transparency:
import QtQuick 2.0
import QtQuick.Window 2.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Item {
id: mainRectangle
anchors.centerIn: parent
width: loaderId.width + 60
height: loaderId.height + 60
opacity: 0.5
layer.enabled: true
Rectangle {
id: rect2
anchors.right: mainRectangle.right
anchors.top: mainRectangle.top
anchors.rightMargin: -30
anchors.topMargin: -30
width: 100
height: 100
color: "red"
}
Loader {
id: loaderId
anchors.centerIn: parent
sourceComponent: component
active: true
}
}
Component {
id: component
Rectangle {
id: rect
width: 100
height: 100
color: "black"
MouseArea {
anchors.fill: parent
onClicked: {
console.log("Clicked!")
// call a signal from here
}
}
}
}
}

Qt Quick layout changes on different events

When I execute my QML code, the output is:
When I minimize the window, It becomes like
and finally, when I again maximize the window it changes to
the GUI which I want to make looks like
![][5]
I am not getting what is the issue for all of the changes in GUI at different events. And this is the Qml code which I wrote
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Layouts 1.3
Window {
visible: true
width: 1080
height: 720
title: qsTr("Login")
GridLayout{
Rectangle{
id:one
Rectangle
{ id:two
color:"black";
width: 700
height:40
}
Image {
id: image
x: 470
y: 0
width: 54
height: 42
source: "qrc:/user.png"
}
Rectangle
{
id:three;
color:"#f47a42";
width: 200
height:40
anchors.left:two.right;
anchors.margins:940
Text {
id: user
text: qsTr("4200")
color:"white"
anchors.top: value.bottom
}
Text
{
id: value;
text: qsTr("User");
color:"yellow"
}}
}
}
Rectangle{
ColumnLayout{
width: 50
height: childrenRect.height+fillHeight;
}
color:"green"
}
}
So why this is happening and how can I solve this problem?
Output of the code below
Here is example of scalable window:
import QtQuick 2.11
import QtQuick.Window 2.11
import QtQuick.Layouts 1.11
Window {
visible: true
width: 800
height: 600
title: qsTr("Layout example")
ColumnLayout{
spacing: 0
anchors.fill: parent
Item {
id: titlebar
Layout.preferredHeight: 40
Layout.fillWidth: true
RowLayout {
anchors.fill: parent
spacing: 0
Rectangle {
Layout.fillWidth: true
Layout.fillHeight: true
color: "orange"
Text {
anchors.centerIn: parent
text: "Title"
}
}
Rectangle {
Layout.preferredWidth: 100
Layout.fillHeight: true
color: "lightgreen"
Text {
anchors.centerIn: parent
text: "Actions"
}
}
}
}
Rectangle {
id: content
Layout.fillHeight: true
Layout.fillWidth: true
color: "lightyellow"
Text {
anchors.centerIn: parent
text: "Content"
}
}
}
}

How to hide an image using transparent rectangle in QML?

In the below code I want to hide the image using transparent rectangle. Please give me some solutions. I have used z value but it is not working. The image is still visible.
main.qml
import QtQuick 2.5
import QtQuick.Window 2.2
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Image
{
id:underlyingImage
width: 400
height: 400
x:0;
y:0;
source:"qrc:/Jellyfish.jpg"
z:1
}
Rectangle
{
id:hiding_rect
width: 400
height: 400
x:0;
y:0;
color:"transparent"
z:100
}
}
You can use the OpacityMask to achieve what you try, in the following example we hide a quadrant of the image.
import QtQuick 2.5
import QtQuick.Window 2.2
import QtGraphicalEffects 1.0
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Image
{
id:underlyingImage
width: 400
height: 400
fillMode: Image.PreserveAspectCrop
layer.enabled: true
layer.effect: OpacityMask {
maskSource: hiding_rect
}
source:"qrc:/Jellyfish.jpg"
}
Rectangle
{
id:hiding_rect
width: underlyingImage.width/2
height: underlyingImage.height/2
}
}
There is another way to use OpacityMask, but your Qt version should be >= 5.7.
import QtQuick 2.0
import QtQuick.Window 2.0
import QtGraphicalEffects 1.0
Window {
width: 1280
height: 800
visible: true
Rectangle {
id: background
anchors.fill: parent
color: "black"
}
Image {
id: underlyingImage
width: 1204
height: 682
visible: false
source: "qrc:/timg.jpg"
}
Item {
id: hidingRect
anchors.fill: underlyingImage
visible: false
Rectangle {
width: underlyingImage.width / 2
height: underlyingImage.height / 2
color: "yellow"
}
}
OpacityMask {
anchors.fill: underlyingImage
source: underlyingImage
maskSource: hidingRect
invert: true
}
}
The result

How to mask a list view in qml?

I have a list view which need to be masked by an image.
Because am using a highlight component whose width need to be reduced according to the scrolling.
Is it possible with this code ? If anything wrong in this please suggest me some methods.
Item{
id: test
x: 0
y: 0
width: 1920
height: 720
ListView {
id: source_list
x: 0
y: 0
width: 600
height: 720
spacing: 40
model: mediaSongsModel
delegate: mediaSongsDelegate
focus: true
interactive: true
highlightFollowsCurrentItem: true
highlightMoveDuration: 0
highlight: highlightBar
snapMode: ListView.SnapOneItem
preferredHighlightBegin:260/scaleFactor
preferredHighlightEnd: 260/scaleFactor
highlightRangeMode : ListView.ApplyRange
}
layer.enabled: true
layer.effect: OpacityMask {
maskSource:Item {
width: 100
height: 500
Image{
id :crop
x: 0
y: 0
width: 600
height: 720
source :"image/bg.png"
}
}
}
}
Something as you already did:
import QtQuick 2.7
import QtQuick.Window 2.2
import QtGraphicalEffects 1.0
Window {
visible: true
width: 600
height: 600
Rectangle {
id: rect
width: 400
height: 400
anchors.centerIn: parent
color: "black"
visible: (img.status == Image.Ready)
ListView {
anchors.fill: parent
model: 30
delegate: Text { text: "itemmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm" + index; color: "yellow" }
}
layer.enabled: true
layer.effect: OpacityMask {
maskSource: img
}
}
Image {
id: img
source: "https://upload.wikimedia.org/wikipedia/commons/thumb/5/53/Google_%22G%22_Logo.svg/1024px-Google_%22G%22_Logo.svg.png"
width: 400
height: 400
anchors.centerIn: parent
visible: false
}
}
But I don't think you can mask mouse events.

Resources