Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Focus issue in SwipeView with Loader
Forum Updated to NodeBB v4.3 + New Features

Focus issue in SwipeView with Loader

Scheduled Pinned Locked Moved Solved QML and Qt Quick
3 Posts 2 Posters 1.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • P Offline
    P Offline
    poor_robert
    wrote on last edited by
    #1

    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?

    DiracsbracketD 1 Reply Last reply
    0
    • P poor_robert

      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?

      DiracsbracketD Offline
      DiracsbracketD Offline
      Diracsbracket
      wrote on last edited by Diracsbracket
      #2

      @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...

      P 1 Reply Last reply
      1
      • DiracsbracketD Diracsbracket

        @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...

        P Offline
        P Offline
        poor_robert
        wrote on last edited by
        #3

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

        1 Reply Last reply
        0

        • Login

        • Login or register to search.
        • First post
          Last post
        0
        • Categories
        • Recent
        • Tags
        • Popular
        • Users
        • Groups
        • Search
        • Get Qt Extensions
        • Unsolved