QT quick-Popup彈出窗口自定義的實現(xiàn)
1.Popup介紹
Popup是一個彈出窗口的控件
它的常用屬性如下所示:
- anchors.centerIn : Object,用來設(shè)置居中在誰窗口中.
- closePolicy : enumeration,設(shè)置彈出窗口的關(guān)閉策略,默認值為默認值為Popup.CloseOnEscape|Popup.CloseOnPressOutside,取值有:
- Popup.NoAutoClose : 只有在手動調(diào)用close()后,彈出窗口才會關(guān)閉(比如加載進度時,不XIANG)。
- Popup.CloseOnPressOutside : 當鼠標按在彈出窗口外時,彈出窗口將關(guān)閉。
- Popup.CloseOnPressOutsideParent : 當鼠標按在其父項之外時,彈出窗口將關(guān)閉。
- Popup.CloseOnReleaseOutside : 當鼠標在彈出窗口外部松開按下時,彈出窗口將關(guān)閉。
- Popup.CloseOnReleaseOutsideParent : 當鼠標在其父項松開按下時,彈出窗口將關(guān)閉。
- Popup.CloseOnEscape : 當彈出窗口具有活動焦點時,按下ESC鍵時,彈出窗口將關(guān)閉。
- dim : bool,昏暗屬性,默認為undefined,設(shè)置為false,則模態(tài)窗口彈出后的其它背景不會昏暗
- modal : bool,模態(tài),默認為false(非模態(tài),非阻塞調(diào)用,指出現(xiàn)該對話框時,也可以與父窗口進行交互,此時dim是無效果的)
- enter : Transition,進入彈出窗口時的動畫過渡
- exit : Transition,退出彈出窗口時的動畫過渡
它的信號如下所示:
- void aboutToHide(): 當彈出窗口即將隱藏時,會發(fā)出此信號。
- void aboutToShow(): 當彈出窗口即將顯示時,會發(fā)出此信號。
- void closed(): 當彈出窗口關(guān)閉時發(fā)出此信號。
- void opened(): 打開彈出窗口時發(fā)出此信號。
它的方法如下所示:
- void close(): 關(guān)閉彈出窗口。
- forceActiveFocus(reason = Qt.OtherFocusReason): 強制設(shè)置焦點
- void open() : 打開彈出窗口。
然后我們來自定義實現(xiàn)一個帶指標的popup彈出窗口.
2.自定義Popup
由于Popup的錨布局只有一個anchors.centerIn,假如們想讓Popup位于某個控件的左上方時,必須得自定義一個.
實現(xiàn)截圖如下所示(已上傳群里):

實現(xiàn)效果如下所示:

首先我們需要實現(xiàn)horizontalPosBase和verticalPosBase兩個屬性.來實現(xiàn)Popup位于目標對象的哪個方位.
- 一個是設(shè)置popup在目標對象的水平方向的位置
- 一個是popup在目標對象的垂直方向的位置.
由于我們已經(jīng)知道了方位,那么指標的坐標也就可以自動計算出來了.
具體實現(xiàn)代碼如下所示:
// 指示器方向,根據(jù)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位于目標水平左側(cè)
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位于目標水平右側(cè)
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位于目標的左側(cè),頂部對齊,就可以這樣寫(無需指定popup的X,Y坐標了):
Button {
id: btn
text: "水平左側(cè)-頂部對齊"
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
}
如果我們使用模態(tài)的彈出窗口,并且想設(shè)置彈出窗口外的背景色,可以設(shè)置Overlay.modal附加屬性,比如設(shè)置為談紅色:
Overlay.modal: Rectangle {
color: "#aaffdbe7"
}
效果如下所示:

到此這篇關(guān)于QT quick-Popup彈出窗口自定義的實現(xiàn)的文章就介紹到這了,更多相關(guān)QT quick-Popup彈出窗口內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++實現(xiàn)LeetCode(2.兩個數(shù)字相加)
這篇文章主要介紹了C++實現(xiàn)LeetCode(兩個數(shù)字相加),本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-07-07
VC編程控件類HTControl之CHTGDIManager GDI資源管理類用法解析
這篇文章主要介紹了VC編程控件類HTControl之CHTGDIManager GDI資源管理類用法解析,需要的朋友可以參考下2014-08-08
數(shù)據(jù)結(jié)構(gòu)之數(shù)組翻轉(zhuǎn)的實現(xiàn)方法
這篇文章主要介紹了數(shù)據(jù)結(jié)構(gòu)之數(shù)組翻轉(zhuǎn)的實現(xiàn)方法的相關(guān)資料,這里用幾種實現(xiàn)方法來實現(xiàn)這樣的功能,需要的朋友可以參考下2017-10-10
使用C++實現(xiàn)MySQL數(shù)據(jù)庫連接池
這篇文章主要為大家詳細介紹了如何使用C++實現(xiàn)MySQL數(shù)據(jù)庫連接池,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以了解下2024-03-03
C語言中一些將字符串轉(zhuǎn)換為數(shù)字的函數(shù)小結(jié)
這篇文章主要介紹了C語言中一些將字符串轉(zhuǎn)換為數(shù)字的函數(shù)小結(jié),分別為atoi()函數(shù)和atol()函數(shù)以及atof()函數(shù),需要的朋友可以參考下2015-08-08
C++代碼和可執(zhí)行程序在x86和arm上的區(qū)別介紹
這篇文章主要介紹了C++代碼和可執(zhí)行程序在x86和arm上的區(qū)別,X86和ARM是占據(jù)CPU市場的兩大處理器,各有優(yōu)劣,本文給大家詳細介紹了兩者的區(qū)別,需要的朋友可以參考下2022-07-07

