Python中文
首页
教程
问答
标签
搜索
登录
注册
如何在qscrolArea()上显示QPropertyAnimation()?
回答此问题可获得
20
贡献值,回答如果被采纳可获得
50
分。
<h2>1。简介</h2> <p>我正在windows10上使用<strong>python3.7</strong>并使用<strong>PyQt5</strong>作为GUI。在我的应用程序中,我得到了一个<code>QScrollArea()</code>,里面有一组按钮。单击时,按钮必须移动到区域之外。我使用<code>QPropertyAnimation()</code>来显示移动。你知道吗</p> <p><br/></p> <h2>2。最小、可复制的示例</h2> <p>我创建了一个用于测试的小应用程序。这个应用程序显示了一个小的<code>QScrollArea()</code>,里面有一堆按钮。单击按钮时,它将向右移动:</p> <p><a href="https://i.stack.imgur.com/fWgNj.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/fWgNj.png" alt="enter image description here"/></a></p> <p>代码如下:</p> <pre class="lang-py prettyprint-override"><code>from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import * import sys class MyButton(QPushButton): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setFixedWidth(300) self.setFixedHeight(30) self.clicked.connect(self.animate) return def animate(self): self.anim = QPropertyAnimation(self, b'position') self.anim.setDuration(3000) self.anim.setStartValue(QPointF(self.pos().x(), self.pos().y())) self.anim.setEndValue(QPointF(self.pos().x() + 200, self.pos().y() - 20)) self.anim.start() return def _set_pos_(self, pos): self.move(pos.x(), pos.y()) return position = pyqtProperty(QPointF, fset=_set_pos_) class CustomMainWindow(QMainWindow): def __init__(self): super().__init__() self.setGeometry(100, 100, 600, 300) self.setWindowTitle("ANIMATION TEST") # OUTER FRAME # ============ self.frm = QFrame() self.frm.setStyleSheet(""" QFrame { background: #d3d7cf; border: none; } """) self.lyt = QHBoxLayout() self.frm.setLayout(self.lyt) self.setCentralWidget(self.frm) # BUTTON FRAME # ============= self.btn_frm = QFrame() self.btn_frm.setStyleSheet(""" QFrame { background: #ffffff; border: none; } """) self.btn_frm.setFixedWidth(400) self.btn_frm.setFixedHeight(200) self.btn_lyt = QVBoxLayout() self.btn_lyt.setAlignment(Qt.AlignTop) self.btn_lyt.setSpacing(5) self.btn_frm.setLayout(self.btn_lyt) # SCROLL AREA # ============ self.scrollArea = QScrollArea() self.scrollArea.setStyleSheet(""" QScrollArea { border-style: solid; border-width: 1px; } """) self.scrollArea.setWidget(self.btn_frm) self.scrollArea.setWidgetResizable(True) self.scrollArea.setFixedWidth(400) self.scrollArea.setFixedHeight(150) self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn) self.lyt.addWidget(self.scrollArea) # ADD BUTTONS TO BTN_LAYOUT # ========================== self.btn_lyt.addWidget(MyButton("Foo")) self.btn_lyt.addWidget(MyButton("Bar")) self.btn_lyt.addWidget(MyButton("Baz")) self.btn_lyt.addWidget(MyButton("Qux")) self.show() return if __name__== '__main__': app = QApplication(sys.argv) QApplication.setStyle(QStyleFactory.create('Plastique')) myGUI = CustomMainWindow() sys.exit(app.exec_()) </code></pre> <p><br/></p> <h2>三。问题</h2> <p>当按钮移动时,它停留在<code>QScrollArea()</code>。我需要把它放在一切之上:</p> <p><a href="https://i.stack.imgur.com/433Xa.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/433Xa.png" alt="enter image description here"/></a></p> <p><br/></p> <h2>第四条。解决方案(几乎)</h2> <p>谢谢你@magrif为我指明了正确的方向。多亏了你的建议,我才有了工作。你知道吗</p> <p>所以我将<code>animate()</code>函数改为:</p> <pre class="lang-py prettyprint-override"><code> def animate(self): self.anim = QPropertyAnimation(self, b'position') self.anim.setDuration(3000) startpoint = self.mapToGlobal(self.pos()) endpoint = self.mapToGlobal(QPoint(self.pos().x() + 200, self.pos().y() - 20)) self.setWindowFlags(Qt.Popup) self.show() self.anim.setStartValue(QPointF(startpoint.x(), startpoint.y())) self.anim.setEndValue(QPointF(endpoint.x(), endpoint.y())) self.anim.start() QTimer.singleShot(1000, self.hide) return </code></pre> <p>请注意,我在按钮上安装了一个单次触发计时器。这是因为只要这个按钮表现为“弹出窗口”(因为<code>self.setWindowFlags(Qt.Popup)</code>),Qt eventloop就会被阻塞。不管怎样,一次性计时器对我来说已经足够好了。你知道吗</p> <p>不幸的是我还有一个问题。当我单击第一个按钮Foo时,它从最初的位置开始(几乎)动画。如果我点击另一个按钮,比如<strong>Baz</strong>,它会突然跳下大约100个像素并从那里开始动画。你知道吗</p> <p>我认为这与<code>startpoint = self.mapToGlobal(self.pos())</code>函数以及这些按钮位于<code>QScrollArea()</code>中的事实有关。但我不知道怎么解决这个问题。你知道吗</p> <p><br/></p> <h2>五。目标</h2> <p>我的目的是建立一个鼠标右键菜单,如下所示:</p> <p><a href="https://i.stack.imgur.com/UE23B.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/UE23B.png" alt="enter image description here"/></a></p> <p>当用户单击“抓取并移动”时,按钮应该从<code>QScrollArea()</code>中消失,并快速移向鼠标。当它到达鼠标指针时,按钮应该淡出,并且可以开始<strong>拖放操作。你知道吗</p> <p><sub><b>注:</b>以下与本主题相关的问题是这个问题:<br/><a href="https://stackoverflow.com/questions/56263595/qt-how-to-perform-a-drag-and-drop-without-holding-down-the-mouse-button">Qt: How to perform a drag-and-drop without holding down the mouse button?</a></sub></p>
0 条评论
分类:
Python问答
请先
登录
后评论
默认排序
时间排序
1 个回答
匿名
1天前
擅长:python、mysql、java
<ol> <li><p>使用<code>mapToGlobal()</code>计算按钮的全局坐标。</p></li> <li><p>使用<code>setWindowFlags()</code>和<code>show()</code>设置标志<code>Qt.Popup</code></p></li> <li><p>Init start和end值关联(1)中的全局坐标,并开始动画</p></li> </ol> < C++中的P>作品::</P>
请先
登录
后评论
针对此问题:
更多的回答
关注
89
关注
收藏
1
收藏,
216
浏览
网友 提问于 2天前
相关Python问题
无法使用Django/mongoengine连接到MongoDB(身份验证失败)
9 回答
无法使用Django\u mssql\u后端迁移到外部hos
3 回答
无法使用Django&Python3.4连接到MySql
5 回答
无法使用Django+nginx上载媒体文件
8 回答
无法使用Django1.6导入名称模式
7 回答
无法使用Django1.7和mongodb登录管理站点
2 回答
无法使用Djangoadmin创建项目,进程使用了错误的路径,因为我事先安装了错误的Python
5 回答
无法使用Djangockedi验证CBV中的字段
4 回答
无法使用Djangocketditor上载图像(错误400)
9 回答
无法使用Djangocron进行函数调用
7 回答
无法使用Djangofiler djang上载文件
4 回答
无法使用Djangokronos
5 回答
无法使用Djangomssql provid
10 回答
无法使用Djangomssql连接到带有Django 1.11的MS SQL Server 2016
2 回答
无法使用Djangomssq迁移Django数据库
5 回答
无法使用Djangonox创建用户
1 回答
无法使用Djangopyodb从Django查询SQL Server
8 回答
无法使用Djangopython3ldap连接到ldap
3 回答
无法使用Djangoredis连接到redis
1 回答
无法使用Django中的FK创建新表
10 回答