I have a combobox in qml in a as a TableViewColummn and I define it as follows:
import QtQuick 2.3
import QtQuick.Window 2.2
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
ListModel {
id: comboModel
ListElement {
text: ""
Index: -1
Dims: -1
}
}
TableViewColumn {
id: imageTypeList
role: "ImageType"
title: "Image Type"
width: 100
delegate: Rectangle {
ComboBox {
anchors.verticalCenter: parent.verticalCenter
anchors.margins: 2
model: comboModel
onActivated : {
console.log(comboModel.get(index).Index)
}
}
}
}
My question is that if it is possible to disable a combobox menu item given a index to the item in the ComboBox. So, I would not like to change the underlying model but actually simply disable the item and not allow the user to select it.
Is it possible to disable a ComboBox menu item ... and not allow the user to select it?
Sure, it is possible.
To do it using Quick Controls 2 you need to create ComboBox delegate this way:
import QtQuick 2.6
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
Window {
visible: true
width: 640
height: 200
title: qsTr("Let's disable some items in ComboBox")
ComboBox {
id: control
currentIndex: 0
anchors.centerIn: parent
model: [
{ text: "Enabled item.", enabled: true },
{ text: "Supposed to be disabled. Can't click on it.", enabled: false},
{ text: "Last, but enabled item.", enabled: true}
]
width: 500
textRole: "text"
delegate: ItemDelegate {
width: control.width
text: modelData.text
font.weight: control.currentIndex === index ? Font.DemiBold : Font.Normal
highlighted: ListView.isCurrentItem
enabled: modelData.enabled
}
}
}
If you are using Quick Controls 1, you should provide your own implementation of ComboBox component.
Related
I'm working on a DatePicker control for QtQuick.Controls 2.0 I have problem on drawing popup calendar over other page items. does anyone help me on this ?
Component Screenshot
My DatePicker source code:
import QtQuick 2.0
import QtQuick.Controls 2.0
import QtQuick.Controls 1.4 as OldControls
Rectangle {
id: root
width: childrenRect.width
height: childrenRect.height
clip: true
property bool expanded: false
property bool enabled: true
property alias selectedDate: cal.selectedDate
MouseArea {
height: expanded ? txt.height + cal.height : txt.height
width: expanded ? Math.max(txt.width, cal.width) : txt.width
hoverEnabled: true
enabled: root.enabled
onHoveredChanged: {
expanded = root.enabled && containsMouse
}
TextField {
id: txt
enabled: root.enabled
text: cal.selectedDate
inputMask: "0000-00-00"
}
OldControls.Calendar {
id: cal
anchors.top: txt.bottom
anchors.left: txt.left
visible: expanded
}
}
}
and here is my DatePicker usage in page:
import QtQuick 2.0
import QtQuick.Layouts 1.0
import QtQuick.Controls 2.2
import "./Components"
Item {
anchors.fill: parent
GridLayout {
columns: 2
Text { text: qsTr("Date Filter: ") }
DatePicker {}
Text { text: qsTr("name filter: ") }
TextField {}
}
}
I was trying to implement a tabbed Dialog in QML with the means to reset it to the intial values.
Since tabs are dynamically instantiated, none of the straight forward methods seem to work. The parent Dialog can not reference the inner Combobox and the Combobox can not reference the outer Dialog. How can this be achieved?
import QtQuick 2.3
import QtQuick.Controls 1.4
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1
Dialog {
id: dlg
title: "Settings"
visible: true
standardButtons: StandardButton.Apply | StandardButton.Reset
property string val: ""
onApply: console.log(val)
onReset: {
// RESET COMBOBOX TO DEFAULT
}
TabView {
id: tabView
anchors.fill: parent
Tab {
title: "ValueTab"
id: tabVal
GridLayout {
id: gridVal
anchors.fill: parent
GroupBox {
title: qsTr("Choose value")
id: gb
Layout.fillWidth: true
ColumnLayout {
anchors.fill: parent
id: cl
ComboBox {
id: valueChooser
editable: false
model: ListModel {
id: listModel
ListElement { text: "One" }
ListElement { text: "Two" }
ListElement { text: "Three" }
}
Layout.fillWidth: true
onCurrentTextChanged : val = currentText
}
}
}
}
}
}
}
I am quite unsure, if I got your question right as you say, you can not reference the Dialog from within the Combobox. I can not see the reason why.
Assuming the example of yours contains indeed your problem and all you want to do is to reset the values (and you know the original values) once the reset button is pressed, this is how I would solve it.
Using the Connections-type to connect to the Dialog's reset() from within the Combobox
import QtQuick 2.3
import QtQuick.Controls 1.4
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1
Dialog {
id: dlg
title: "Settings"
visible: true
standardButtons: StandardButton.Apply | StandardButton.Reset
property string val: ""
onApply: console.log(val)
onReset: {
// **DONT** RESET COMBOBOX TO DEFAULT **HERE**
}
TabView {
id: tabView
anchors.fill: parent
Tab {
title: "ValueTab"
id: tabVal
GridLayout {
id: gridVal
anchors.fill: parent
GroupBox {
title: qsTr("Choose value")
id: gb
Layout.fillWidth: true
ColumnLayout {
anchors.fill: parent
id: cl
ComboBox {
id: valueChooser
editable: false
model: ListModel {
id: listModel
ListElement { text: "One" }
ListElement { text: "Two" }
ListElement { text: "Three" }
}
Layout.fillWidth: true
onCurrentTextChanged : val = currentText
/// *** INTERESTING PART HERE! ***
Connections {
target: dlg
onReset: {
// RESET COMBOBOX TO DEFAULT **HERE** INSTEAD
valueChooser.currentIndex = 0
}
}
}
}
}
}
}
}
}
I'd like to arrange for a specific control to get the focus within a TabView Tab. Its seems that the first one gets the focus regardless of what I do. I have tried setting focus:false everywhere else but it doesn't work.
Consider the following code. I have a simple column containing two RadioButtons and a TextField. I'd like to arrange for the TextField to always get focus when the tab is selected, but it always goes to the first RadioButton
import QtQuick 2.7
import QtQuick.Controls 1.4
import QtQuick.Controls.Styles 1.4
import QtQuick.Layouts 1.3
ApplicationWindow
{
visible: true
width: 800
height: 400
TabView
{
anchors.fill: parent
Tab { title: "tab1"; sourceComponent: foo }
Tab { title: "tab2"; sourceComponent: foo }
}
Component
{
id: foo
ColumnLayout
{
spacing: 32
ExclusiveGroup { id: optionGroup }
RadioButton
{
// i always get the focus!!
exclusiveGroup: optionGroup
text: "Click me"
activeFocusOnPress: true
focus: false
}
RadioButton
{
exclusiveGroup: optionGroup
text: "No, click me!"
activeFocusOnPress: true
focus: false
}
TextField
{
// but i want the focus
placeholderText: "type here"
focus: true
}
}
}
}
Press "tab2" to see this,
I tried forcing within TabView by adding,
onCurrentIndexChanged: getTab(currentIndex).item.forceActiveFocus()
But it makes no difference.
I've read the explanation of focus but it hasn't helped in this case.
Thanks for any suggestion or help,
Probably a bug. Try Qt Quick Controls 2.0 instead:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.3
ApplicationWindow {
visible: true
width: 800
height: 400
header: TabBar {
id: bar
width: parent.width
TabButton {
text: qsTr("tab1")
}
TabButton {
text: qsTr("tab2")
}
}
StackLayout {
anchors.fill: parent
currentIndex: bar.currentIndex
ColumnLayout {
id: columnLayout
spacing: 32
ButtonGroup {
id: optionGroup
buttons: columnLayout.children
}
RadioButton {
text: "Click me"
}
RadioButton {
text: "No, click me!"
}
TextField {
placeholderText: "type here"
focus: true
}
}
}
}
I'm learning Qt Quick to make a file manager, but I have no experience in QML or GUI in general. The first step is to list the content of a folder, using FolderListModel. I got the example code working using ListView, but naturally I want to display multiple fields in addition to the name, e.g. size, time, and so on. Thus, I'm thinking of using TableView.
However, it's not clear to me how to delegate each entry as a row in TableView. Currently I'm simply using itemDelegate to display fileName, and the resultant is that in each row, all the columns repeat the name of the entry. So I think rowDelegate is the correct way, but how do I make a proper delegate Component for that purpose? Conceptually I'd like to specify an array of fields, e.g. [model.fileName, model.fileSize] corresponding to the table columns. Is this achievable?
For clarify I'm posting the code below:
import QtQuick 2.4
import QtQuick.Controls 1.4
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1
import Qt.labs.folderlistmodel 2.1
ApplicationWindow {
visible: true
width: 900
height: 600
title: qsTr("Hello World")
Item {
anchors.fill: parent
width: 900
height: 600
SplitView {
id: splitView1
anchors.fill: parent
TabView {
id: tabView1
width: splitView1.width / 2
Tab {
title: qsTr("Home")
TableView {
id: tableView1
width: splitView1.width / 2
TableViewColumn {
role: "name"
title: qsTr("Name")
width: tableView1.width * 0.75
}
TableViewColumn {
role: "size"
title: qsTr("Size")
width: tableView1.width * 0.25
}
FolderListModel {
id: folderModel2
folder: "file:/home/username"
nameFilters: ["*"]
showHidden: true
}
Component {
id: fileDelegate2
Text {
text: model.fileName
}
}
model: folderModel2
itemDelegate: fileDelegate2
}
}
}
}
}
}
The documentation mentions that the following roles are available:
List item
fileName
filePath
fileURL (since Qt 5.2)
fileBaseName
fileSuffix
fileSize
fileModified
fileAccessed
fileIsDir
So you don't need to have custom delegates to display that information, just set the role property of TableViewColumn appropriately:
import QtQuick 2.4
import QtQuick.Controls 1.4
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.1
import Qt.labs.folderlistmodel 2.1
ApplicationWindow {
visible: true
width: 900
height: 600
title: qsTr("Hello World")
Item {
anchors.fill: parent
width: 900
height: 600
SplitView {
id: splitView1
anchors.fill: parent
TabView {
id: tabView1
width: splitView1.width / 2
Tab {
title: qsTr("Home")
TableView {
id: tableView1
width: splitView1.width / 2
TableViewColumn {
role: "fileName"
title: qsTr("Name")
width: tableView1.width * 0.75
}
TableViewColumn {
role: "fileSize"
title: qsTr("Size")
width: tableView1.width * 0.25
}
FolderListModel {
id: folderModel2
folder: "file:/home/username"
nameFilters: ["*"]
showHidden: true
}
model: folderModel2
}
}
}
}
}
}
I created a component (SidebarMenuButton) that is used in the main qml file multiple times. The button has styles that should be inherited by all it's 'instances'. Here is the SidebarMenuButton.qml:
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
Button {
width: buttonNewMessage.width
height: buttonNewMessage.height
anchors {
horizontalCenter: parent.horizontalCenter
topMargin: 5
}
style: ButtonStyle {
background: Rectangle {
color: 'transparent'
}
label: Text {
text: parent.text // undefined here
color: 'white'
font.family: 'Helvetica'
font.pixelSize: 12
font.bold: true
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
}
}
}
And a part of my main qml file:
import QtQuick 2.3
import QtQuick.Window 2.1
import QtQuick.Layouts 1.1
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
Window {
id: main
title: 'Messenger'
width: 1024
height: 768
minimumWidth: 800
minimumHeight: 600
RowLayout {
id: layout
anchors.fill: parent
spacing: 0
Rectangle {
id: sidebar
color: '#3C3E55'
Layout.fillHeight: true
Layout.preferredWidth: 200
ButtonCompanyName {
id: buttonCompanyName
}
ButtonNewMessage {
id: buttonNewMessage
}
SidebarMenuButton {
id: buttonInbox
text: 'Inbox (1)'
anchors.top: buttonNewMessage.bottom
}
SidebarMenuButton {
id: buttonSentMessages
text: 'Sent messages'
anchors.top: buttonInbox.bottom
}
SidebarMenuButton {
id: buttonStarred
text: 'Starred'
anchors.top: buttonSentMessages.bottom
}
}
I commented the line with error. parent there doesn't refer to button so the text in all buttons is empty. I need to access parent button from there and get it's text property. The component has no id cause it's used multiple times and ids are assigned in the main qml file. So the question is: how can I get that button text without id?
There are two ways to set text in your case.
1)The Button for which you are applying the style is available as control property in ButtonStyle class. You can set the the text as text:control.text
Reference:control property(ButtonStyle)
2)You can give an id to the Button in SidebarMenuButton type and access its textproperty.
Button
{
id:button
.
.
.
text: button.text
}
You can assign an id inside your component file that would not conflict with the id you use when you instantiate the component somewhere else. I use the same value for the id of most of my QML components: container so that I can easily reference properties from the root of the item.
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
Button {
id: container
style: ButtonStyle {
background: Rectangle {
color: 'transparent'
}
label: Text {
text: container.text
}
}
}
Then when you instantiate this component in another file you set whichever id you want and it would still work