How to write conditional import statements in QML?
Depending on what you want to achieve, a possible workaround is to use a Loader. But it does not import a module, it just allows to choose dynamically which QML component you'll use.
Loader
{
source: condition?"RedRectangle.qml":"BlueRectangle.qml"
}
QML import later module version only if available?
Conditional imports were requested as a feature for Qt 4.7, but have not been implemented yet; see the bug report for details.
However, it's possible to use a Loader
to make sure that the import
failure does not prevent the rest of the GUI from loading. This is outlined in one of the comments in the bug-report discussion.
FAILING CASE:
// MyContainer.qml
Item {
AlwaysAvailableType {
// ... etc
}
SometimesNonworkingType {
id: nonworking_thing
// ... FAILS to load!
}
}
Here, we assume that SometimesNonworkingType.qml
contains the import
statement that will fail on some systems but not others. When the QML engine tries to load MyContainer
, it will fail, causing the entire QML loading operation to fail.
FIXED VERSION:
// MyContainer.qml
Item {
AlwaysAvailableType {
// ... etc
}
Loader {
source: "SometimesNonworkingType.qml"
property bool valid: item !== null
id: maybeworking_thing
// ... etc
}
}
maybeworking_thing.valid
can be used to check if the SometimesNonworkingType
was actually successfully loaded.
(Credit for finding the bug report: How to write conditional import statements in QML?)
QML how to create different types based on a condition
Try it with a Loader
Loader {
property bool shouldBeText
Component { id: rect; Rectangle {}}
Component { id: text; Text {}}
sourceComponent: shouldBeText ? text : rect
}
If statement in QML
You can do it like this:
color: (hand.callValue >= hand.handRaiseXBB) ? hand.handFoldColor : hand.handCallColor
You could also make a function to calculate it and then assign the color property with the return value of the function:
function getHandColor()
{
var handColor = hand.handCallColor
if(hand.callValue >= hand.handRaiseXBB)
{
handColor = hand.handFoldColor
}
return handColor
}
color: getHandColor()
Custom Button with conditional image and conditional text
As @BaCaRoZzo already suggested, using styles is preferable solution in this case since the item itself is still Button
and so you can use all its properties and signals, including text
property to pass your ueText
text.
As for hiding elements inside, you can use visible
property as suggested below:
UeButton.qml
Button {
id: ueButton
style: ButtonStyle {
background: Rectangle {
color: control.pressed ? "#CCC" : "#DEDEDE"
border.width: 1
border.color: "#999"
radius: 3
}
label: ColumnLayout {
id: layout
spacing: 10
Image {
Layout.alignment: Qt.AlignHCenter
source: control.iconSource
visible: control.iconSource !== ""
}
Text {
text: control.text
visible: control.text !== ""
}
}
}
}
Now using of this component is similar to regular Button
:
UeButton {
anchors.centerIn: parent
text: "Some text"
iconSource: "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7"
}
Commenting out text
or iconSource
will change the button view
Introduce condition in delegate
As @derM comments one option is to use Loader, in the following example each point has an attribute called type that serves to distinguish which items should be drawn a rectangle or circle.
Marker.qml
import QtQuick 2.0
import QtLocation 5.6
MapQuickItem {
sourceItem: Loader{
sourceComponent:
if(type == 0)//some condition
return idRect
else if(type == 1) //another condition
return idCircle
}
Component{
id: idRect
Rectangle{
width: 20
height: 20
color: "blue"
}
}
Component{
id: idCircle
Rectangle{
color: "red"
width: 20
height: 20
radius: 50
}
}
}
main.qml
MapItemView {
model: navaidsModel
delegate: Marker{
coordinate: position
}
}
Output:
You can find a complete example in the following link.
How to simulate C-style ifdef macro in QML?
As @Mark suggested, context properties can be used in QML to decide in run time if some macro is enabled or not, but the example he provides does not address the case, when you need to instantiate an object based on this decision, but only covers case when inside a code block. So I will provide the full example of what I did.
In my case I exposed a class to QML only when a macro was defined during compile time:
main.cpp:
#ifdef SMTP_SUPPORT
qmlRegisterType<SmtpClientHelper>("com.some.plugin", 1, 0, "SmtpClient");
engine.rootContext()->setContextProperty("SMTP_SUPPORT", QVariant(true));
#else
engine.rootContext()->setContextProperty("SMTP_SUPPORT", QVariant(false));
#endif // SMTP_SUPPORT
Then on QML side I check this macro and decide if SmtpClient object must be created:
qml:
import QtQuick 2.0;
import com.some.plugin 1.0
Item {
id: root
// ...
property var smtpClient // No inside any function, need to instantiate the object
Component.onCompleted: {
if (SMTP_SUPPORT) {
smtpClient = Qt.createQmlObject(' \
import QtQuick 2.0; \
import com.some.plugin 1.0; \
SmtpClient { \
id: smtpClient; \
\
function setSenderEmail(email) { \
senderEmail = email; \
storage.save("common", "clientEmail", email); \
} \
} \
', root, "SmtpClient");
}
}
// Reference smtpClient normally, like if it was statically created
TextInput {
id: senderEmailLogin
anchors.fill: parent
font.pixelSize: Globals.defaultFontSize
text: smtpClient ? smtpClient.senderEmail : ""
onEditingFinished: if (smtpClient) smtpClient.setSenderEmail(text)
activeFocusOnPress: true
}
}
I think Loader should also do the job, so you could create a separate component, reference it in Loader's source
or sourceComponent
properties if C++ macro is defined, but I am not sure, because not sure if this component will be statically checked if (in my case) SmtpClient
type is available
Related Topics
How to Print a String to the Terminal in X86-64 Assembly (Nasm) Without Syscall
Does Linux Time Division Processes or Threads
How to Strip Path While Archiving with Tar
Where to Get Msbuild for Linux
Linux/Ubuntu Set: Illegal Option -O Pipefail
Linker Error on Linux: "Undefined Reference To"
How to Install Xvfb (X Virtual Framebuffer) on Redhat 6.5
How to Respond to Prompts in a Linux Bash Script Automatically
How to Get Docker Container Id from Within the Container with Cgroup V2
How to Write Conditional Import Statements in Qml
Use Crontab Job Send Mail, the Email Text Turns to an Attached File Which Named Att00001.Bin
Linux Raw Ethernet Socket Bind to Specific Protocol
How to Reset Emacs to Save Files in Utf-8-Unix Character Encoding
Embed Icc Color Profile in PDF