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" }
效果如下所示: