Material Style In Qml Does Not Load Colors - qt

i used methods here to use material design in my QtQuick project and used Accent and Themes from here controls loading in material style correctly in normal qml files , but in qml files loaded by loader result is like this:
this loader is in main.qml :
Loader{
id:myLoader
anchors.fill: parent
source: "LoginPage.qml"
}
and here is my dynamic qml file
import QtQuick 2.8
import QtQuick.Controls 2.1
import QtQuick.Controls.Material 2.3
import QtGraphicalEffects 1.0
Rectangle{
Material.theme: Material.Dark
Material.accent: Material.Teal
property string error_msg: ""
id: loginPage
Button {
id: button
width: 80
anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right
anchors.rightMargin: 0
font.family: "B Nazanin"
enabled: webView.loadProgress == 100 ? true:false
KeyNavigation.tab: button1
Material.accent: Material.Orange
onClicked: {
login()
}
}
}

The dark there is presumed to have a dark background. It will not set your window background for you, it only affects GUI controls. And the button in particular doesn't use use the accent color, just the foreground color, unless toggle is enabled, in which case it will use the accent color to signify that.
Material.theme: Material.Dark
Material.accent: Material.Teal
Rectangle {
anchors.fill: r2
color: "#262626"
}
Row {
id: r1
Button {
text: "test"
checkable: true
Material.accent: Material.Orange
}
Button {
text: "test"
checkable: true
}
}
Rectangle {
anchors.fill: r2
}
Row {
id: r2
anchors.top: r1.bottom
Button {
text: "test"
checkable: true
Material.accent: Material.Orange
}
Button {
text: "test"
checkable: true
}
}
As you see, on a white background, the dark theme button looks blurry and washed out. If you want to set the button color, that would be the Material.background whereas the text would be Material.foreground.

I had a similar problem.
Just use ApplicationWindow as your root element and it will work.
And additionally you have to load Material before instantiating QML.
QGuiApplication application(argc, argv);
QQmlApplicationEngine engine;
QQuickStyle::setStyle("Material");

Related

qt quick material style controls

I'm trying to design a qt quick application using qml. From what I gather in the documentation of qt is that these controls have support for styling automatically (e.g. there's a material light/material dark themes.
However, when I tried to apply it to the tabview control I can't get the styling to be applied. I can make a propery binding ala Rectangle { color: Material.color(Material.Red)} This works well for looking up any of the predefined colors, however I don't seem to be able to access attached (inherited) properties like Material.background
How can I best apply theming to controls that don't support it? It doesn't look like it's possible to property binding to an attached property- or at least qt/qml seems to get confused because Material. is also considered the namespace.
import QtQuick 2.9
import QtQuick.Window 2.3
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import QtQuick.Controls.Styles 1.2
import QtQuick.Controls.Material 2.1
ApplicationWindow {
id: mainWindow;
visible: true
width: 640
height: 480
title: qsTr("Hello World")
Material.theme: Material.Dark
Material.accent: Material.Purple
TabView {
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
tabPosition: Qt.BottomEdge
Material.theme: Material.Dark
Material.accent: Material.Purple
Tab {
title: "Red"
Material.theme: Material.Dark
Material.accent: Material.Purple
}
Tab {
title: "Blue"
Rectangle { color: "blue" }
}
Tab {
title: "Green"
Material.theme: Material.Dark
Material.accent: Material.Purple
}
style: TabViewStyle {
frameOverlap: 1
tab: Rectangle {
color: styleData.selected ? "steelblue" :"lightsteelblue"
border.color: "steelblue"
implicitWidth: Math.max(text.width + 4, 80)
implicitHeight: 20
radius: 2
Text {
id: text
anchors.centerIn: parent
text: styleData.title
color: styleData.selected ? "white" : "black"
}
}
frame: Item {
}
}
}
}
TabView is from Controls 1. You should use TabBar and TabButton, as the Material style is only available with Qt Quick Controls 2:
https://doc.qt.io/qt-5/qtquickcontrols2-differences.html#type-comparison-table

Why does my SwipeView page not change when I change the Tab in the TabBar in QML?

So, I'm trying to create a traditional look for my QML application which simply consists of a TabBar and a SwipeView. There's also another component which essentially boils down to a button click which should result in a new tab in the TabBar and a new page in the SwipeView. This works, except that when I click on the previous tab (there's a static tab and page when the app starts up), the page in the view doesn't change.
Here's my QML file -
import QtQuick 2.12
import QtQuick.Layouts 1.3
import QtGraphicalEffects 1.12
import QtQuick.Controls 2.13
ColumnLayout {
Layout.fillHeight: true
Layout.fillWidth: true
Component {
id: tabButton
TabButton {
width: implicitWidth
}
}
Component {
id: resultListView
Rectangle {
anchors.fill: parent
color: "green"
}
}
SwipeView {
id: tabBarLayout
Layout.fillHeight: true
Layout.fillWidth: true
interactive: false
currentIndex: 0
LogArea {
id: logArea
}
}
TabBar {
id: tabBar
currentIndex: tabBarLayout.currentIndex
Layout.fillWidth: true
font.capitalization: Font.MixedCase
TabButton {
text: qsTr("log")
width: implicitWidth
}
Connections {
target: qmlBridge
onLoadResultTab: {
tabBar.addItem(tabButton.createObject(tabBar, {text: qsTr("search - " + term)}))
tabBarLayout.addItem(resultListView.createObject())
tabBarLayout.incrementCurrentIndex()
console.log("Added new item...")
}
}
}
}
The onLoadResultTab signal is invoked when the button is clicked. As you can see, I'm adding a new TabButton and incrementing the current index and then creating another component which is just a simple Rectangle for now. Now, when I click on the "log" button, the SwipeView doesn't change its page to the one corresponding to the log tab. Could anyone point out what's the issue here?

QML: Buttons become transparet over images using Material Style

I want my application to use an image as a Background. So I use this code:
In my ApplicationWindow:
Image {
id: bkgImage
source: "qrc:/images/bkg.jpg"
anchors.centerIn: parent
}
To add a button
Button {
id: btnAsistencia
text: qsTr("ASISTENCIA")
font.pixelSize: fhButttonTextSize
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: btnInscripcion.bottom
anchors.topMargin: parent.height*0.1
}
The code above is for the second button, but I added one before in the exact same way. This is the result:
The second button becomes transparent over the image. How can I prevent this?
You can set the background colour of the button with the Material.background attached property:
import QtQuick 2.0
import QtQuick.Controls 2.0
import QtQuick.Controls.Material 2.0
ApplicationWindow {
id: window
width: 400
height: 440
visible: true
color: "red"
Button {
text: qsTr("ASISTENCIA")
Material.background: "#666"
}
}
The default colour has some transparency:
http://code.qt.io/cgit/qt/qtquickcontrols2.git/tree/src/imports/controls/material/qquickmaterialstyle.cpp#n862

How should I start QML files?

I have 4 QML files: MainMenu.qml, AppArea.qml, Result.qml and main.qml.
When my app starts, I want to see first page as MainMenu.qml fullscreen. There is a button (on MainMenu.qml) to start AppArea.qml. When I click the the button, I want to start AppArea.qml as fullscreen new window.
There is a button (on AppArea.qml), when I click that button, I want to show Result.qml but I want to see Result.qml on AppArea.qml, I mean when Result.qml come outs, AppArea.qml will not disappear but Result.qml will appear on AppArea.qml.
There is a button on Result.qml. When I click the button, the Repeater in AppArea.qml will regenerate, because maybe model of Repeater changing like 1, 2, 3, 4.... There is a button on AppArea.qml, when I click the button, I want to open MainMenu.qml as a fullscreen new window like AppArea.qml.
Actually you can think basic: My app is a game like this:
How way should I choose for these jobs?
In addition to the mentioned post, in your case you are using the component from qml file, so you need to load the component first, your main.qml can be like this:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.2
Window {
id: mainWindow
title: "Main window"
visible: true
flags: Qt.Dialog
modality: Qt.ApplicationModal
Loader{
id: mainMenuLoader
}
Component.onCompleted: {
mainMenuLoader.source="mainMenu.qml"
var mainMenu = mainMenuLoader.item.createObject(mainWindow);
mainWindow.hide()
}
}
and your mainMenu.qml can look like this:
import QtQuick 2.9
import QtQuick.Window 2.3
import QtQuick.Controls 2.2
Component {
id: mainMenu
Window {
id:mmenu
title: "Main Menu"
width: 600
height: 600
visible: true
flags: Qt.Dialog
modality: Qt.ApplicationModal
Loader{
id: appAreaLoader
}
Text {
text: "This is mainMenu"
}
Button{
id: loadAppArea
anchors.centerIn: parent
text: "Start Game"
onClicked: {
appAreaLoader.source="appArea.qml"
var appArea = appAreaLoader.item.createObject(mainMenu);
hide()
}
}
}
}
you will need to do the same for successive windows ...etc.
While for result, you need to use a MouseArea:
appArea.qml:
Component {
id: appMenu
Window {
id:appMenuWindow
title: "App Menu"
width: 600
height: 600
visible: true
flags: Qt.Dialog
modality: Qt.ApplicationModal
Loader{
id:anotherLoader
visible: true
anchors.left: appMenuText.left
anchors.top: appMenuText.bottom
width: parent.width/3
height: parent.height/3
}
Text {
id: appMenuText
text: "This is App Area"
anchors.centerIn: parent
}
Button{
id: loadResult
text: "Show Result"
onClicked: {
anotherLoader.source = "result.qml"
anotherLoader.visible=true
}
}
Button{
anchors.right: parent.right
id: loadMainMenu
text: "Open main Menu"
onClicked: {
hide()
//mmenu.show()
anotherLoader.setSource("main.qml")
}
}
}
}
result.qml:
Rectangle{
color: "green"
Text {
anchors.centerIn: parent
id: resultxt
text: qsTr("This is result, Click to close")
}
MouseArea {
anchors.fill: parent
onClicked: { anotherLoader.visible = false
}
}
}

How to make visible both icon and text on QML ToolButton

I am creating desktop application using QML and QtQuick.Components. I want to place on the toolbar buttons like the standard MacOS settings dialogs do:
I use ToolBar and ToolButton, but I can't find the way to do it. For instance with the following code it shows icons only:
ApplicationWindow {
// ...
toolBar: ToolBar {
RowLayout {
ToolButton {
text: qsTr("Main")
iconSource: "main.png"
}
ToolButton {
text: qsTr("System")
iconSource: "system.png"
}
ToolButton {
text: qsTr("Items Book")
iconSource: "itemsbook.png"
}
}
}
}
And it seems like ToolButton can show either text or icon:
Text {
id: textitem
text: button.text
anchors.centerIn: parent
visible: button.iconSource == "" // <=========
}
A simple yet a powerful approach is to create own QML component.
Create a custom QML component / file:
File -> New File or Project -> Qt -> QML File (choose latest version).
Now enter file name, for example MyToolButton.
Note that it will be also used as
component name.
Add there neccesary imports and code:
MyToolButton.qml (customize for your needs)
import QtQuick 2.0
import QtQuick.Controls 1.4
ToolButton
{
Image {
source: parent.iconSource
fillMode: Image.PreserveAspectFit // For not stretching image (optional)
anchors.fill: parent
anchors.margins: 2 // Leaving space between image and borders (optional)
anchors.bottomMargin:10 // Leaving space for text in bottom
}
Text {
text: parent.text
anchors.bottom: parent.bottom // Placing text in bottom
anchors.margins: 2 // Leaving space between text and borders (optional)
anchors.horizontalCenter: parent.horizontalCenter // Centering text
renderType: Text.NativeRendering // Rendering type (optional)
}
}
Main.QML (where you want to use it):
import QtQuick 2.0
import QtQuick.Controls 1.4
// Usual toolbar declaration
ToolBar {
id: mainToolBar
RowLayout {
// Create MyToolButton. Note that component name (MyToolButton) is the same as file name.
MyToolButton {
id:tbQuit
// Way 1: Add here any icon
iconSource: "qrc:///images/quit.png"
text:qsTr("&Quit")
// Way 2, my favourite: Convert your Action into Button!
action: actQuit
}
}
}
Action {
id: actQuit
text: qsTr("&Quit")
onTriggered: Qt.quit()
shortcut: "Alt+Q"
iconSource: "qrc:///Images/Exit.png"
}
Notes:
It requires QtQuick.Controls 1.4 and should work on Qt 5.2+. (Worked fine on Qt 5.5).
Don't forget to add imports.
Code parts marked as (optional) can be skipped.
Replace ToolButton with Button and it will work as a Button.
Hope it helps!
Have you try to add your own Text control like this:
ApplicationWindow {
// ...
toolBar: ToolBar {
RowLayout {
ToolButton {
text: qsTr("Main")
iconSource: "main.png"
Text {
text: parent.text
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
}
}
ToolButton {
text: qsTr("System")
iconSource: "system.png"
Text {
text: parent.text
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
}
}
ToolButton {
text: qsTr("Items Book")
iconSource: "itemsbook.png"
Text {
text: parent.text
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
}
}
}
}
}
And set the ToolButton height with the right value (image + text height)

Resources