1.Popup介紹

Popup是一個彈出視窗的控制元件
它的常用屬性如下所示:

  • anchors.centerIn : Object,用來設定居中在誰視窗中.
  • closePolicy : enumeration,設定彈出視窗的關閉策略,預設值為預設值為Popup.CloseOnEscape|Popup.CloseOnPressOutside,取值有:
    • Popup.NoAutoClose : 只有在手動呼叫close()後,彈出窗口才會關閉(比如載入進度時,不XIANG)。
    • Popup.CloseOnPressOutside : 當滑鼠按在彈出視窗外時,彈出視窗將關閉。
    • Popup.CloseOnPressOutsideParent : 當滑鼠按在其父項之外時,彈出視窗將關閉。
    • Popup.CloseOnReleaseOutside : 當滑鼠在彈出視窗外部鬆開按下時,彈出視窗將關閉。
    • Popup.CloseOnReleaseOutsideParent : 當滑鼠在其父項鬆開按下時,彈出視窗將關閉。
    • Popup.CloseOnEscape : 當彈出視窗具有活動焦點時,按下ESC鍵時,彈出視窗將關閉。
  • dim : bool,昏暗屬性,預設為undefined,設定為false,則模態視窗彈出後的其它背景不會昏暗
  • modal : bool,模態,預設為false(非模態,非阻塞呼叫,指出現該對話方塊時,也可以與父視窗進行互動,此時dim是無效果的)
  • enter : Transition,進入彈出視窗時的動畫過渡
  • exit : Transition,退出彈出視窗時的動畫過渡

它的訊號如下所示:

  • void aboutToHide(): 當彈出視窗即將隱藏時,會發出此訊號。
  • void aboutToShow(): 當彈出視窗即將顯示時,會發出此訊號。
  • void closed(): 當彈出視窗關閉時發出此訊號。
  • void opened(): 開啟彈出視窗時發出此訊號。

它的方法如下所示:

  • void close(): 關閉彈出視窗。
  • forceActiveFocus(reason = Qt.OtherFocusReason): 強制設定焦點
  • void open() : 開啟彈出視窗。

然後我們來自定義實現一個帶指標的popup彈出視窗.

2.自定義Popup
由於Popup的錨佈局只有一個anchors.centerIn,假如們想讓Popup位於某個控制元件的左上方時,必須得自定義一個.
實現截圖如下所示(已上傳群裡):

 實現效果如下所示:

首先我們需要實現horizontalPosBase和verticalPosBase兩個屬性.來實現Popup位於目標物件的哪個方位.

  • 一個是設定popup在目標物件的水平方向的位置
  • 一個是popup在目標物件的垂直方向的位置.

由於我們已經知道了方位,那麼指標的座標也就可以自動計算出來了.
具體實現程式碼如下所示:

     // 指示器方向,根據horizontalPosBase和verticalPosBase 自動計算
enum IndicatorStyle {
IndicatorLeft,
IndicatorRight,
IndicatorTop,
IndicatorBottom
} function updateIndicatorPos(indicatorStyle) {
switch (indicatorStyle)
{
case IndicatorPopup.IndicatorLeft:
indicator.x = - indicator.width*0.4;
indicator.y = back.height <= myTarget.height ? (back.height)/2-indicatorLen :
verticalPosBase === IndicatorPopup.TopAlign ? (myTarget.height)/2 -indicatorLen :
verticalPosBase === IndicatorPopup.VerticalAlign ? (back.height)/2 -indicatorLen :
back.height - (myTarget.height)/2 -indicatorLen; break; case IndicatorPopup.IndicatorRight:
indicator.x = width - indicator.width*1.2;
indicator.y = back.height <= myTarget.height ? (back.height)/2-indicatorLen :
verticalPosBase === IndicatorPopup.TopAlign ? (myTarget.height)/2 -indicatorLen :
verticalPosBase === IndicatorPopup.VerticalAlign ? (back.height)/2 -indicatorLen :
back.height - (myTarget.height)/2 -indicatorLen;
break; case IndicatorPopup.IndicatorTop:
indicator.x = back.width <= myTarget.width ? (back.width)/2-indicatorLen :
horizontalPosBase === IndicatorPopup.PosBaseToRight ? (myTarget.width)/2 -indicatorLen :
horizontalPosBase === IndicatorPopup.PosBaseToHorizontal ? (back.width)/2 -indicatorLen :
back.width - (myTarget.width)/2 -indicatorLen;
indicator.y = - indicator.width*0.4;
break;
case IndicatorPopup.IndicatorBottom:
indicator.x = back.width <= myTarget.width ? (back.width)/2-indicatorLen :
horizontalPosBase === IndicatorPopup.PosBaseToRight ? (myTarget.width)/2 -indicatorLen :
horizontalPosBase === IndicatorPopup.PosBaseToHorizontal ? (back.width)/2 -indicatorLen :
back.width - (myTarget.width)/2 -indicatorLen;
indicator.y = height - indicator.height*1.2;
break;
}
console.log("indicator",indicator.x,indicator.y,indicator.width,indicator.height)
} function updatePopupPos() {
var indicatorStyle; switch (horizontalPosBase)
{
case IndicatorPopup.PosBaseToLeft: // popup位於目標水平左側 x = myTarget.x - width - targetSpacing;
y = verticalPosBase === IndicatorPopup.TopAlign ? myTarget.y :
verticalPosBase === IndicatorPopup.VerticalAlign ? myTarget.y + myTarget.height/2 - height/2 :
myTarget.y - height + myTarget.height
indicatorStyle = IndicatorPopup.IndicatorRight; break; case IndicatorPopup.PosBaseToHorizontal: // popup水平中間
x = myTarget.x + myTarget.width/2 - width/2;
y = verticalPosBase === IndicatorPopup.PosBaseToTop ? myTarget.y - height - targetSpacing :
verticalPosBase === IndicatorPopup.PosBaseToBottom ? myTarget.y + myTarget.height + targetSpacing :
myTarget.y + myTarget.height + targetSpacing indicatorStyle = verticalPosBase === IndicatorPopup.PosBaseToTop ? IndicatorPopup.IndicatorBottom :
IndicatorPopup.IndicatorTop; break; case IndicatorPopup.PosBaseToRight: // popup位於目標水平右側 x = myTarget.x + myTarget.width + targetSpacing;
y = verticalPosBase === IndicatorPopup.TopAlign ? myTarget.y :
verticalPosBase === IndicatorPopup.VerticalAlign ? myTarget.y + myTarget.height/2 - height/2 :
myTarget.y - height + myTarget.height
indicatorStyle = IndicatorPopup.IndicatorLeft
console.log("PosBaseToRight",x,y,indicatorStyle);
break;
} back.anchors.leftMargin = indicatorStyle === IndicatorPopup.IndicatorLeft ? indicatorLen : 0
back.anchors.rightMargin = indicatorStyle === IndicatorPopup.IndicatorRight ? indicatorLen : 0
back.anchors.bottomMargin = indicatorStyle === IndicatorPopup.IndicatorBottom ? indicatorLen : 0
back.anchors.topMargin = indicatorStyle === IndicatorPopup.IndicatorTop ? indicatorLen : 0 leftPadding = indicatorStyle === IndicatorPopup.IndicatorLeft ? indicatorLen : 0
rightPadding = indicatorStyle === IndicatorPopup.IndicatorRight ? indicatorLen : 0
bottomPadding = indicatorStyle === IndicatorPopup.IndicatorBottom ? indicatorLen : 0
topPadding = indicatorStyle === IndicatorPopup.IndicatorTop ? indicatorLen : 0 console.log(x,y,indicatorStyle); updateIndicatorPos(indicatorStyle); }

比如我們想讓這個popup位於目標的左側,頂部對齊,就可以這樣寫(無需指定popup的X,Y座標了):

Button {
id: btn
text: "水平左側-頂部對齊"
onClicked: {
popup.backgroundColor = "#12B7F5"
popup.horizontalPosBase = IndicatorPopup.PosBaseToLeft
popup.verticalPosBase = IndicatorPopup.TopAlign
popup.indicatorOpen(btn)
}
} IndicatorPopup {
id: popup
width : 180
height: 200
modal: false
focus: true
parent: Overlay.overlay // Overlay.overlay表示主視窗的意思,附加到任何的item、popup中,避免當前介面不是主介面的情況,無法顯示彈出視窗 TextArea {
anchors.fill: parent
text: "1234567890"
color: "#FFF"
font.pixelSize: 14
font.family: "Microsoft Yahei"
wrapMode: TextEdit.WrapAnywhere
} closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
}

如果我們使用模態的彈出視窗,並且想設定彈出視窗外的背景色,可以設定Overlay.modal附加屬性,比如設定為談紅色:

Overlay.modal: Rectangle {
color: "#aaffdbe7"
}

效果如下所示: