Focus issue in SwipeView with Loader



  • Hello Qt developers :),

    I have problem with proper setting the focus of the Item. There is SwipeView which contains 2 pages. One of these pages ihas Loader. Here how the qml file looks like:

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    import QtQuick.Layouts 1.3
    
    ApplicationWindow {
    	visible: true
    	width: 640
    	height: 480
    	title: qsTr("Hello World")
    
    	objectName: "AppWindow"
    
    	FocusScope
    	{
    		anchors.fill: parent
    		focus: true
    
    		SwipeView {
    			id: swipeView
    			objectName: "SwipeView"
    			anchors.fill: parent
    			currentIndex: tabBar.currentIndex
    
    			Rectangle
    			{
    				Loader
    				{
    					id: pageLoader
    					anchors.centerIn: parent
    					focus: true
    				}
    			}
    
    			Page {
    				Label {
    					text: qsTr("Second page")
    					anchors.centerIn: parent
    				}
    			}
    		}
    	}
    
    	footer: TabBar {
    		id: tabBar
    		currentIndex: swipeView.currentIndex
    		TabButton {
    			text: qsTr("First")
    		}
    		TabButton {
    			text: qsTr("Second")
    		}
    	}
    
    	Component.onCompleted:
    	{
    		console.log("App Window OnCompleted")
    		pageLoader.setSource("Page1.qml")
    //		pageLoader.forceActiveFocus()
    	}
    }
    

    And there is also "Page1.qml":

    import QtQuick 2.7
    import QtQuick.Controls 2.0
    import QtQuick.Layouts 1.3
    
    Item {
    	objectName: "Page1 Item"
    	property alias textField1: textField1
    	property alias button1: button1
    
    	RowLayout {
    		objectName: "Page1 RowLayout"
    		anchors.horizontalCenter: parent.horizontalCenter
    		anchors.topMargin: 20
    		anchors.top: parent.top
    
    		TextField {
    			id: textField1
    			objectName: "TextField1"
    			placeholderText: qsTr("Text Field")
    			focus: true
    		}
    
    		Button {
    			id: button1
    			text: qsTr("Press Me")
    		}
    	}
    
    	Component.onCompleted:
    	{
    		console.log("Page1 onCompleted")
    //		textField1.forceActiveFocus()
    	}
    }
    

    I would like to have to focus inside the TextField so just after the application start I can type somethig with my keyboard. I would like to get this focus without using methods like Item.forceActiveFocus() etc. Best solution for me would be to use FocusScope and focus property.

    Do you have any clue how to properly setup FocusScope, SwipeView and Loader?



  • @poor_robert
    Your pages are inside a SwipeView, whose pages are made children of its contentItem and thus set both the focus of the SwipeView and its contentItem to true (somehow, setting only contentItem.focus to true does not work. Also set the Loader's focus to true. The following works without using any forceActiveFocus():

    1. Eliminate the FocusScope in your ApplicationWindow: not needed:
    ApplicationWindow {
    ...
           //Get rid of this, no use
    	FocusScope
    	{
            }
    }
    
    1. Then:
        SwipeView {
            id: swipeView
            objectName: "SwipeView"
            anchors.fill: parent
            currentIndex: tabBar.currentIndex
    
            focus: true
            contentItem.focus: true
    
            Page {
                Loader
                {
                    focus: true
                    id: pageLoader
                    anchors.centerIn: parent
                    source: "page1.qml"
                }
            }
    
            Page {
                Label {
                    text: qsTr("Second page")
                    anchors.centerIn: parent
                }
            }
        }
    

    Loader is itself a FocusScope, so if you don't want to force focus on individual elements of your loaded page, you can still force it upon the Loader as a whole, and let the Loader's internal FocusScope do its job. Then you don't need to set the focus on the SwipeView and its contentItem:

                Loader
                {
                    focus: true
                    id: pageLoader
                    anchors.centerIn: parent
                    source: "page1.qml"
                    onLoaded: forceActiveFocus()
                }
    

    Also, as a side note, why don't you simplify your Page1.qml as follows:

    RowLayout {
        objectName: "Page1 RowLayout"
        anchors.horizontalCenter: parent.horizontalCenter
        anchors.topMargin: 20
        anchors.top: parent.top
    
        TextField {
            id: textField1
            objectName: "TextField1"
            placeholderText: qsTr("Text Field")
            focus: true
        }
    
        Button {
            id: button1
            text: qsTr("Press Me")
        }
    }
    

    No need to wrap it in a superfluous Item, unless of course, you have other plans... I used to do such unnecessary wrapping myself when I started learning QML not so long ago...



  • @Diracsbracket Thank you, this works as expected :).


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.