Popup

 

Web的桌面提醒:Popup一,什么是Popup 

在IE5.
5+中开始支持的Popup窗口有很多很特别的特性: 

Popup窗口可以超出浏览器窗口区域; 
可以不用担心被下拉框、flash、Iframe等这些东西遮挡; 
即时窗口没有焦点,Popup窗口也可以弹出并显示 
一个Popup窗口打开后,当在它的区域以外点击或者另一个Popup窗口被打开时都会自动关闭; 
Popup窗口是没有焦点的; 
用户不能改变Popup窗口大小; 
Popup窗口中的内容是不能被选择的; 
...... 
只是Web下的Popup比起Windows中的Popup还是弱一些,但是已经够用了。Msdn上对Popup有非常详细的介绍“Using the Popup Object (Internet Explorer 
- DHTML) ” 

二,怎么创建一个Popup 

Msdn上的示例代码: 
// 创建Popup对象var oPopup = window.createPopup();// Popup对象和Window对象一样,里面包含了一个完整的HTML文档var oPopupBody = oPopup.document.body;// 在Body中插入HTMLoPopupBody.innerHTML = "Display some <B>HTML</B> here.";// 设置显示的位置、大小、参照物oPopup.show(100, 100, 200, 50, document.body); 
三,Popup的显示 

多个Popup不能共存(Popup中创建Popup除外),所以web中的Popup不方便像Msn Messenger的Popup提示那样“爬楼梯”,所以最简单有效的方法就是像Outlook2003的Popup一样,逐个Popup提醒。 
(参考WebMessenger的实现)用Js建个队列,将需要Popup提示的内容都放在队列中,用一个定时器,定时从队列中取一个Popup,每个Popup显示7秒。 

四,怎么知道有新帖子 

在Web程序中,只能通过“拉”的技术,即定时向服务器发送请求——通过定时刷新或者是xmlhttp的Get。 
我们需要有个时间戳来记录最后请求时间,这样就好根据这个时间戳来获取时间戳之后的帖子。 
如果每次根据时间戳来获取最新帖子,服务器负荷比较大,因为并不是每次请求都有新帖子的,优化一下,再给每个在线用户设置有无新帖子、有无新留言的状态位,当发表新帖子后更新每个人的“有无新帖”状态位。这样每次请求时先判断有没有新帖子,如果有新帖子,才获取所有帖子的标题和内容简要。 


使用Popup窗口创建无限级Web页菜单

在Web上使用菜单可以极大地节约页面的空间,同时也比较的符合用户从Windows上继承下来的UI操作体验。在以往的Web页菜单设计中,我们普遍使用div嵌套table的方式来实现菜单,这样的菜单有个最致命的问题就是会被
<select>覆盖。我们为了解决这个问题,有时我们干脆在显示图层菜单的同时隐藏页面上的所有下拉列表框,在菜单消失的时候,再显示他们。这个方法虽然可以解决问题,而其优化过后还可以只隐藏和下拉列表框相交的列表框,但是这些解决方法都不是十分的完美。还有些小问题,这样的菜单定位很困难,因为在<div>显示的时候,用户可以使用鼠标滚轮滚动页面,这样一来是否要让<div>菜单和页面滚动同步呢?如果不要,页面被滚走了,菜单仍显示在一个和自己毫不相关的位置上很是古怪。如果要同步,那么噩梦就来了,因为被滚动的区域不一定就是<body>区域,还可能是一些类似<div style="overflow:auto"><div>的区域,要算出菜单的位置将会非常的麻烦。 

下面将介绍的Popup来实现的Web页菜单将完全解决
<div>做为菜单容器时遇到的问题,Popup窗口是IE5.5及以后版本提供的一个新feature。什么是popup呢?简单说popup其实就是一个弹出窗口,它拥有以下特点(MSDN描述): 
·popup窗口在用户点击它自身之外的任何地方或另一个popup打开的时候会自动关闭; 
·popup在显示的时候不能获得焦点,所以用户已focused的操作将继续在其父窗口中执行; 
·组成popup的DHTML可以存储在其父document或其他的document元素中; 
·popup窗口中不支持文本框一类的编辑框element; 
·不能选中popup窗口中的元素; 
·不能在popup窗口中navigate(点击popup中的连接,不能让更新的内容显示到这个popup中); 
·popup窗口一旦显示就不能移动和resize。 

这里MSDN说的不全,而且有的地方不是很准确,popup窗口还有几个重要的特性。它可以超出浏览器的窗口范围而且也不会被下拉框、flash、IFrame等这些元素遮挡。实际上popup里的内容是可以被选择的,不知道MSDN说的不能选择是啥意思
?。关于MSDN说popup不能获得焦点也有点问题,其实是popup里的编辑框类控件不能获得焦点,而其它的非可编辑控件是可以获得焦点的。而且popup显示的时候,IE主窗口不能获得鼠标的onmousewheel事件。 
这样的一些特性,恰好表明了popup窗口非常的适合用来制作弹出菜单,并且由于popup窗口显示的时候,IE窗口内的文档是不能被移动的,这样就不存在context menu的位置同步问题了,因为毕竟popup窗口不能move(move位置需要hide以后在新的位置上重show),这个问题还比较讨厌。 

使用popup窗口制作无限级别的菜单,有两个问题要解决:一个是要能在一个IE中显示多个Popup窗口,二是要能把窗口中的一些事件俘获并执行我们脚本过程。MSDN在描述popup窗口特性时,第一条就说了只要有另一个popup窗口开启,先前显示的popup窗口就会自动关闭。这下怎么办呢?不过既然都说了要实现无限级的菜单了,办法还是有的。对于popup,使用方式其实是很简单的,他一共就只包含了两个方法:hide()和show(...),和两个属性:document和isOpen。虽然在IE中我们连续的调用n次window.createPopup().show(...)只能出来一个popup窗口被显示,可是我们可以调用popup.document.parentWindow的createPopup方法,它产生的popup窗口在显示的时候就不会关闭前面已显示的popup窗口,并且对于新的popup用这个方法可以继续开启child popup。这个问题再研究下去,会发现IE实现popup的一些怪异的地方(当然这些对于我们实现这个菜单关系不太大,只是觉得混乱)。 

比如我们在一个IE窗口中,
var popup = window.createPopup(); var win = popup.document.parentWindow; 我们会发现 window != win,对于多个popup可以共存,这个不相等还能理解,但是当我们调用win.resizeTo(...)的时候,我们发现父IE窗口被resize了。同样我们在popup中select all,结果也是父IE窗口里的内容被全选了@_@... 

使用Popup窗口创建无限级Web页菜单(
2

上次我说到要使用popup在web中创建无限级菜单,两个要解决的问题是多个popup窗口共存和popup中的事件的处理。其中多个popup共存的问题我已经讲了可以使用popup.document的parentWindow来再createPopup,这个就算搞定了,而第二个问题就有些让人讨厌了,为什么呢? 

    我们通过createPopup创建的popup对象包含了一个document属性,document其实就是html的容器。MSDN说:构建popup的DHTML可以存储在其父document或其他的document中。这个话真是让人不明白,其实就是说我们可以使用popup.document.body去append别的DHTML内容,比如:popup.document.body.innerHTML 
= '...'或popup.document.body.appendChild(...)。这里又遇到了popup的一些怪异的特性,我们发现: var win = window; 
var doc = win.document;  
var popup = win.createPopup(); 
var popdoc = popup.document; 
var popwin = popdoc.parentWindow; 
var popwindoc = popwin.document;      结果popdoc != popwindoc,这都没什么了,不等就不等把,可是当我们调用popdoc.write和popwindoc.write后,去发现执行结果是一样的,即数据被写入了popup窗口中。不过还好这里也不影响我们的菜单实现,就是怪异罢了。 

    上面的popdoc和popwindoc引用虽然不同,不过执行效果却相同,都能按我们预期的效果修改popup。可是接下来我们发现popup.document.body的appandChild方法和innerHTML属性向popup里添加DHTML内容的效果就大不同了,这个不同和给我带了很多的麻烦,使菜单的逻辑数据(JavaScript构建的菜单类)与UI表现(HTML元素构建的菜单的可视外观)以及它们之间的事件传递变得乱糟糟的。 

    我们有两个方法向popup里添加html内容,一个是使用popup.document.body的innerHTML直接把html代码赋到body中去;另一个办法是使用popup.document.body的appendChild方法对dom进行操作。这里要注意,必须使用popup自己的document对象来创建DHTML元素,才能使用appendChild来添加。比如我上面代码中的popdoc和popwindoc虽然引用不相等,但是确实是popup的doucment对象,使用他们来createElement得到的对象,才能被appendChild到popup里去。如果是使用doc来createElement得到的对象,在popup.docuemnt.body上去appendChild会得到一个运行时错误:Error: Invalid argument.。 

    为什么啰里啰唆说了半天appendChild方法和innerHTML属性呢?因为他们各有各的好处,如果使用appendChild这种方式,我们可以在创建菜单类的数据的时候,使菜单的逻辑数据(JavaScript实现的类)和UI显示元素(HTML)之间彼此引用起来,这样在我们处理菜单事件的时候,会使程序和整个执行结构都变得比较清晰(这个在菜单处理事件的时候,我会再详细说)。这样一说,我们当然应该使用这种方法来append我们的菜单的内容了,可是我们又遇到了popup一个让人抓狂的问题。使用popup.document.body.appendChild方法把DHTML内容导入后,我们事先赋给DHMTL元素的属性有些会失效,其中包括nowrap, onstartselect, rules等,这三个属性的失效,十分严重的影响了菜单UI的呈现,下图就是使用appendChild后popup窗口里得到的效果,左边是在IE里我们希望的正确效果。  

所以不得不放弃了appendChild方法的使用,改用popup.document.body.innerHTML直接赋值html的办法,可是这种方法就不能在对象引用关系上建立菜单逻辑数据和UI元素之间的联系,因为对象引用虽然能被存储在html元素的属性中,可是当以字符串方式来复制html元素时,html元素上attach的事件和属性里存放的对象引用就都丢失了,所以只能使用另外的办法来关联他们。于是我们实现了一个叫__MenuCache__的类似hash table的全局类来管理它们之间的一一对应关系。  


用Popup对象构建网页右键菜单

代码如下: 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 
<html> 
<head> 
<TITLE>Popup对象实现右键菜单</TITLE> 
<script language="JavaScript"> 
var oPopup = window.createPopup(); 
function contextMenu() 


var left = event.offsetX+10
var top = event.offsetY+10
oPopup.document.body.innerHTML 
= oContext.innerHTML; 
oPopup.show(left, top, 
12080, window.document.body); 

}
 
</script> 
</head> 
<body oncontextmenu="contextMenu(); return false;"> 
<h1>Popup对象实现右键菜单</h1> 
单击鼠标右键查看效果 
<div ID="oContext" style="DISPLAY: none; BACKGROUND: #e4e4e4; "> 
<div onmouseover="this.style.background='gold'" 
onmouseout
="this.style.background='#e4e4e4'" 
<span onclick='parent.location.href="http://www.zol.com.cn"'> 
中关村在线
</span> 
</div> 
<div onmouseover="this.style.background='gold'" 
onmouseout
="this.style.background='#e4e4e4'" 
<span onclick="parent.location.href='http://www.cfan.com.cn'"> 
电脑爱好者
</span> 
</div> 
<div onmouseover="this.style.background='gold';" 
onmouseout
="this.style.background='#e4e4e4';"> 
<span onclick="parent.location.href='http://www.sina.com.cn'"> 
新浪网
</span> 
</div> 
<div onmouseover="this.style.background='gold'" 
onmouseout
="this.style.background='#e4e4e4'" 
<span onclick="parent.location.href='http://www.xinhuanet.com'"> 
新华网
</span> 
</div> 

</div> 
</body> 
</html> 



<think>我们正在讨论QML中的Popup组件的使用方法和示例。根据Qt文档,Popup是QtQuick.Controls模块中的一个组件,它用于创建一个可以弹出的覆盖层。Popup通常用于对话框、菜单工具提示等。我将介绍Popup的基本用法、常用属性、信号以及一个简单的示例。基本用法:Popup组件提供了一个基本的弹出窗口,可以设置其内容。它有一个重要的属性是`visible`,用于控制Popup的显示和隐藏。其他常用属性包括:-modal:是否模态,模态弹出会阻止背景交互-dim:是否在非模态时变暗背景(仅对ApplicationWindow有效)-closePolicy:控制Popup关闭的条件,例如点击外部按ESC键-x,y:弹出位置重要信号:-opened:当Popup打开时发出-closed:当Popup关闭时发出示例1:一个简单的Popup以下示例展示了如何创建一个包含文本和按钮的Popup,点击按钮关闭Popup。```qmlimportQtQuick2.12importQtQuick.Controls2.12ApplicationWindow{visible:truewidth:400height:400Button{text:"打开弹出框"onClicked:popup.open()}Popup{id:popupx:100y:100width:200height:300modal:truefocus:trueclosePolicy:Popup.CloseOnEscape|Popup.CloseOnPressOutsideParentColumn{anchors.fill:parentText{text:"这是一个弹出窗口"}Button{text:"关闭"onClicked:popup.close()}}}}```在这个示例中,我们创建了一个ApplicationWindow,其中包含一个按钮。点击按钮会打开弹出框。弹出框内部有一个列布局,包含一个文本和一个关闭按钮。注意:Popup的关闭策略(closePolicy)我们设置为按ESC键者点击Popup窗口外部时关闭。这里我们设置`modal`为true,所以弹出时背景会被半透明的遮罩层覆盖,并且阻止背景的交互。示例2:使用锚定布局的Popup通常,我们希望Popup出现在窗口的中间,这时可以使用锚定布局。```qmlPopup{id:popupanchors.centerIn:Overlay.overlay//注意:这里锚定到Overlay.overlay,而不是parentwidth:200height:300modal:true//...内容同上}```注意:在ApplicationWindow中,我们可以使用`Overlay.overlay`来获取主窗口的覆盖层,这样我们就能将Popup居中显示。示例3:带进入/退出动画的Popup我们可以通过添加进入和退出动画来美化Popup。```qmlPopup{id:popup//...其他属性同上enter:Transition{NumberAnimation{property:"opacity";from:0.0;to:1.0;duration:200}}exit:Transition{NumberAnimation{property:"opacity";from:1.0;to:0.0;duration:200}}}```在以上代码中,我们为Popup添加了淡入淡出效果。注意事项:1.Popup对象必须是ApplicationWindow者Window。如果在一个Item中,需要确保这个Item是窗口的顶层Item。2.模态弹出(modal:true)会捕获所有的鼠标事件,防止背景交互,直到弹出窗口被关闭。3.如果使用非模态,并且希望点击外部关闭,可以设置`closePolicy:Popup.CloseOnPressOutside`。更多详细用法,请参考Qt官方文档。§§相关问题§§1.如何在QML中使用Menu组件?2.QtQuickControls2中还有哪些常用的对话框组件?3.如何在Popup中嵌入复杂的自定义内容?</think> ### QML Popup 组件用法详解 Popup 是 Qt Quick Controls 2 中的核心组件,用于创建覆盖在界面上的模态/非模态弹出层[^1]。以下是完整使用指南: #### 基础用法 ```qml import QtQuick.Controls 2.15 Popup { id: msgPopup x: 100 y: 50 width: 200 height: 150 modal: true focus: true Label { text: "操作成功!" anchors.centerIn: parent } // 自动关闭计时器 Timer { interval: 2000 running: msgPopup.visible onTriggered: msgPopup.close() } } ``` #### 关键属性 | 属性 | 说明 | 示例 | |------|------|------| | `modal` | 是否阻塞背景交互 | `modal: true` | | `dim` | 背景遮罩(仅限ApplicationWindow) | `dim: true` | | `closePolicy` | 关闭条件控制 | `closePolicy: Popup.CloseOnEscape|Popup.CloseOnPressOutside` | | `padding` | 内容边距 | `padding: 10` | | `overlay.parent` | 指定覆盖层 | `Overlay.overlay: parent` | #### 进阶示例:带动画的对话框 ```qml Popup { id: dialog anchors.centerIn: Overlay.overlay width: 300; height: 200 enter: Transition { ParallelAnimation { NumberAnimation { property: "scale"; from: 0.8; to: 1.0; duration: 200 } NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; duration: 200 } } } background: Rectangle { radius: 8 color: "white" border { color: "#2196F3"; width: 2 } } contentItem: Column { padding: 20 Label { text: "确认删除?"; font.bold: true } Row { spacing: 10 Button { text: "取消"; onClicked: dialog.close() } Button { text: "确认"; primary: true } } } } ``` #### 最佳实践 1. 使用 `anchors.centerIn: Overlay.overlay` 居中弹窗 2. 通过 `onOpened`/`onClosed` 信号处理业务逻辑: ```qml Popup { onOpened: console.log("弹窗已打开") onClosed: { // 释放资源 editor.text = "" } } ``` 3. 需要嵌套事件循环时使用`QEventLoop::exec()`[^2] #### 常见问题解决 - **焦点丢失问题**:设置`focus: true`和`closePolicy: Popup.CloseOnPressOutsideParent` - **位置偏移**:避免使用绝对坐标,改用锚布局 - **层问题**:在`ApplicationWindow`中优先声明Popup组件 官方完整示例参考:[Qt Quick Controls 2 - Popup Example](https://doc.qt.io/qt-6/qtquick-controls2-popup.html)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值