2015-11-04 66 views
3

我有一個虛擬鍵盤,它從屏幕底部彈出並始終保持在最前端。我將在我的應用程序中使用它,並有一個小問題。在使用屏幕鍵盤時保持輸入字段在屏幕中

如果接受來自此鍵盤的輸入的文本輸入字段位於視圖的中間/底部(主窗口/屏幕),則它隱藏在鍵盤後面,即在隱藏鍵盤之前無法看到輸入內容。

鍵盤作爲platforminputcontext插件運行,它將知道接受輸入的字段。

void KeyboardPlatformInputContext::setFocusObject(QObject* object) 
{ 
    qDebug() << m_focusedObject << object; 
    m_focusedObject = object; 
} 

當按下按鍵,它們是作爲QEvents通過這樣

void KeyboardPlatformInputContext::processNormalKeyClick(const QString& key) 
{ 
    qDebug() << m_focusedObject << key; 
    if (m_focusedObject) { 
     QInputMethodEvent inputEvent; 
     inputEvent.setCommitString(key); 
     QGuiApplication::sendEvent(m_focusedObject, &inputEvent); 
    } 
} 

現在,隨着可用信息(m_focusedObjectQGuiApplication),也可以是可以做些什麼來保持輸入字段在視圖中。總是。

+1

首先,您需要一種機制來移動整個UI。你必須弄清楚你的特定用例會起什麼作用。然後用它來移動東西,以便聚焦的控件可見,如果它不是從頭開始。 –

回答

1

庫巴有正確的想法;我只是擴展它。例如,您可以使用Flickable來管理應用程序的內容。例如,假設您的應用程序佈局就像一個表格:

import QtQuick 2.0 
import QtQuick.Window 2.0 

Window { 
    id: root 
    width: 480 
    height: 800 
    visible: true 

    Column { 
     anchors.fill: parent 
     anchors.margins: 20 
     spacing: 20 

     Repeater { 
      model: 20 

      Row { 
       spacing: 20 

       Text { 
        text: "Input #" + (index + 1) 
        anchors.verticalCenter: parent.verticalCenter 
       } 
       TextInput { 
        width: 100 
        height: 30 

        onActiveFocusChanged: { 
         if (activeFocus) 
          keyboardRect.visible = activeFocus 
        } 

        Rectangle { 
         border.width: 1 
         anchors.fill: parent 
         anchors.margins: -1 
         z: -1 
        } 
       } 
      } 
     } 
    } 

    Rectangle { 
     id: keyboardRect 
     width: parent.width 
     height: parent.height * 0.3 
     anchors.bottom: parent.bottom 
     color: "grey" 
     visible: false 
    } 
} 

,使其可用一個虛擬鍵盤,內容移動到Flickable

import QtQuick 2.0 
import QtQuick.Window 2.0 

Window { 
    id: root 
    width: 480 
    height: 800 
    visible: true 

    Flickable { 
     id: flickable 
     anchors.fill: parent 
     anchors.margins: 20 
     anchors.bottomMargin: keyboardRect.visible ? keyboardRect.height : anchors.margins 
     contentWidth: column.implicitWidth 
     contentHeight: column.implicitHeight 
     flickableDirection: Flickable.VerticalFlick 

     Column { 
      id: column 
      spacing: 20 

      Repeater { 
       model: 20 

       Row { 
        spacing: 20 

        Text { 
         text: "Input #" + (index + 1) 
         anchors.verticalCenter: parent.verticalCenter 
        } 
        TextInput { 
         width: 100 
         height: 30 

         onActiveFocusChanged: { 
          if (activeFocus) { 
           keyboardRect.visible = activeFocus 

           var posWithinFlickable = mapToItem(column, 0, height/2); 
           flickable.contentY = posWithinFlickable.y - flickable.height/2; 
          } 
         } 

         Rectangle { 
          border.width: 1 
          anchors.fill: parent 
          anchors.margins: -1 
          z: -1 
         } 
        } 
       } 
      } 
     } 
    } 

    Rectangle { 
     id: keyboardRect 
     width: parent.width 
     height: parent.height * 0.3 
     anchors.bottom: parent.bottom 
     color: "grey" 
     visible: false 
    } 
} 

有幾件事情需要注意:

anchors.bottomMargin: keyboardRect.visible ? keyboardRect.height : anchors.margins 

這確保了內容爲「推」了,當鍵盤是可見的,所以,沒有什麼是隱藏在它下面。

onActiveFocusChanged: { 
    if (activeFocus) { 
     keyboardRect.visible = activeFocus 

     var posWithinFlickable = mapToItem(column, 0, height/2); 
     flickable.contentY = posWithinFlickable.y - flickable.height/2; 
    } 
} 

此代碼沒有考慮失去焦點,因此鍵盤始終保持打開狀態。

我們通過將字段位置映射到Column來將Flickable集中在當前輸入字段上。

最後,當您點擊列頂部或底部附近的字段時,您會看到有點跳躍。如果字段靠近頂部或底部,則可以通過不設置contentY來解決這個問題。給讀者一個練習。 :)