我有一个简单的QScrollarea
,其QWidget
内部有一个垂直框布局,其中包含许多小部件。我在点击鼠标并在QLineEdit中输入文本后添加新的小部件。
但是,滚动区域的行为会有所不同,具体取决于导致插入新项目的原因。如果在addTestLabel()
信号后调用我的textChanged()
,则整个内容会跳转一秒钟,但是如果从鼠标点击事件中调用相同的addTestLabel()
,它的工作方式应该完全正常,对我有意义。
Gif示例,首先我通过单击插入项目并且它完美地工作,然后我通过键入开始插入并且它跳转。然后我回去点击它,它在第一次点击后跳转但是然后所有进一步的点击插入而不再跳跃
我可以做的最短的例子:
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QWidget, QApplication, QScrollArea, QVBoxLayout, QSizePolicy, QLineEdit
from ui.tabdock.utils import *
class ChatView(QWidget):
def __init__(self):
super().__init__()
#make the main window a vertical box layout
self._boxLayout = QVBoxLayout()
self._boxLayout.setAlignment(Qt.AlignTop)
self.setLayout(self._boxLayout)
# make a scroll area and put it at the top
self._scrollArea = QScrollArea()
self._scrollArea.setWidgetResizable(True)
self._boxLayout.addWidget(self._scrollArea)
# add a text input below the scroll area
self._textInput = QLineEdit()
# make it add a new item every time textChange event fires
#THIS RESULTS IN EVERYTHING JUMPING FOR A SECOND
self._textInput.textChanged.connect(lambda t: self.addTestLabel("text change add"))
self._boxLayout.addWidget(self._textInput)
# make a container view with a vertical box layout that will contain all the actual items
self.listContainerView = QWidget()
self.listContainerView.setLayout(QVBoxLayout())
self.listContainerView.layout().setAlignment(Qt.AlignTop)
# put the container view inside the scroll area
self._scrollArea.setWidget(self.listContainerView)
#some items to get started
for i in range(10):
self.addTestLabel("label %s"%i)
#add new items whenever the mouse is pressed somewhere
# THIS INSERTS CORRECTLY WITHOUT JUMPING
self.mousePressEvent = lambda e:self.addTestLabel()
def addTestLabel(self, text = "complex widget goes here"):
label = QLabel(text)
label.setStyleSheet("border: 1px solid red;")
label.setFixedHeight(50)
self.listContainerView.layout().addWidget(label)
if __name__ == '__main__':
app = QApplication(sys.argv)
cv = ChatView()
cv.show()
cv.setGeometry(400,400,1200,800)
sys.exit(app.exec_())
如果从addTestLabel()
信号调用textChanged
并使其行为与从鼠标点击调用时的行为相同,如何停止跳跃的瞬间?
答案 0 :(得分:1)
事实证明问题是每当scrollarea及其容器视图不在焦点上时,就像我在文本框中键入并且有焦点一样,在向容器添加内容后,它不会立即更新几何体和布局小部件,所以它会看起来很奇怪,直到它开始更新它。
添加小部件后添加self.listContainerView.updateGeometry()
以强制布局刷新修复它。