最近在做一个类似QQ的局域网消息传输软件,当发送消息或者接收到消息时,滚动条应该自动滚动到最下方。
刚开始想的是在发送或接收消息并创建提示信息后,执行如下代码
self.scrollBar.setValue(self.scrollBar.maximum())
这样做发现滚动条是可以向下动,但是不会到最下方,也就是说会有一点点空隙。
bebug发现原因是增加滚动区域高度后,maximum方法获取的值还是原本的值,也就是还没有来得及更新。
解决方案:
设置一个标志位
self.scrollButtonFlag = False
连接rangeChanged信号
self.scrollBar.rangeChanged.connect(self.handleScrollBarRangeChanged)
在需要移动滚动条的时候,将标志位置为True
def handleSendBtnClicked(self):
self.createItem()
self.scrollButtonFlag = True
对应的槽函数
def handleScrollBarRangeChanged(self, minValue, maxValue):
if self.scrollButtonFlag:
self.scrollBar.setValue(maxValue)
self.scrollButtonFlag = False
设置这个标志位是为了防止手动改变滚动区域范围(比如说resize)的时候,滚动条的位置错误移动。
运行效果
启动的时候
点击发送按钮后
滚动条正常移动到最下方
将滚动条移动到某个位置,然后进行resize
resize前后滚动条的位置不发生改变
完整代码
runner.py
import sys
import source_rc
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from shyQUI.shyQUI import Ui_MainWindow
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setupUi(self)
for i in range(5):
self.createItem()
self.sendBtn.clicked.connect(self.handleSendBtnClicked)
self.scrollBar = self.displayScrollArea.verticalScrollBar()
self.scrollBar.rangeChanged.connect(self.handleScrollBarRangeChanged)
self.scrollButtonFlag = False
def createItem(self):
headLabel = QLabel(self.displayFrame)
headLabel.setPixmap(QPixmap(r':/head/icons/computer.png'))
headLabel.setFixedSize(30, 30)
hbox = QHBoxLayout(self.displayFrame)
hbox.addWidget(headLabel)
self.verticalLayout_2.addLayout(hbox)
headLabel.show()
def handleScrollBarRangeChanged(self, minValue, maxValue):
if self.scrollButtonFlag:
self.scrollBar.setValue(maxValue)
self.scrollButtonFlag = False
def handleSendBtnClicked(self):
self.createItem()
self.scrollButtonFlag = True
if __name__ == '__main__':
app = QApplication(sys.argv)
main = MainWindow()
main.setGeometry(200, 100, 800, 200)
main.show()
sys.exit(app.exec_())
shyQUI.py
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'shyQUI.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
MainWindow.setStyleSheet("#MainWindow {\n"
"background-color: #ffffff;\n"
"}\n"
"#displayFrame {\n"
" padding: 3px 10px;\n"
"}\n"
"#sendBtn {\n"
" color: #ffffff;\n"
" background-color: rgb(58,146,217);\n"
" border-radius: 5px;\n"
" padding: 3px 10px;\n"
" text-align: center;\n"
" font-family: \'微软雅黑\';\n"
" margin-right: 10px;\n"
" font-size:14px;\n"
"}\n"
"\n"
"#line {\n"
"color: rgb(234,234,234);;\n"
" background-color:rgb(234,234,234);\n"
"border: none;\n"
"}\n"
"#sendTextEdit {\n"
" border: none;\n"
"font-family: \'微软雅黑\';\n"
"font-size: 14px;\n"
"}")
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setStyleSheet("/*设置整个滚动条*/\n"
"QScrollBar:vertical {\n"
" background-clip:margin;\n"
" background:transparent;\n"
" width: 8px;\n"
"}\n"
"\n"
"/*设置滚动条的滑块*/\n"
"QScrollBar::handle:vertical {\n"
" width:8px;\n"
" background:rgb(205,205,205);\n"
" border-radius:4px;\n"
" min-height:20;\n"
"}\n"
"\n"
"/*鼠标放在滑块上*/\n"
"QScrollBar::handle:vertical:hover {\n"
" background: rgb(153,153,153);\n"
"}\n"
"\n"
"/*设置滚动条的增加页和减少页区域*/\n"
"QScrollBar::add-page:vertical,\n"
"QScrollBar::sub-page:vertical{\n"
" background:transparent;\n"
"}\n"
"\n"
"/*隐藏上下箭头和按钮*/\n"
"QScrollBar::add-line:vertical,\n"
" QScrollBar::sub-line:vertical{\n"
" border: none;\n"
"}")
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setSpacing(0)
self.verticalLayout.setObjectName("verticalLayout")
self.displayScrollArea = QtWidgets.QScrollArea(self.centralwidget)
self.displayScrollArea.setStyleSheet("* {\n"
"border:none;\n"
"background-color: #fff;\n"
"}\n"
"\n"
"\n"
"")
self.displayScrollArea.setWidgetResizable(True)
self.displayScrollArea.setObjectName("displayScrollArea")
self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 800, 158))
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.scrollAreaWidgetContents)
self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.displayFrame = QtWidgets.QFrame(self.scrollAreaWidgetContents)
self.displayFrame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.displayFrame.setFrameShadow(QtWidgets.QFrame.Raised)
self.displayFrame.setObjectName("displayFrame")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.displayFrame)
self.verticalLayout_2.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.verticalLayout_3.addWidget(self.displayFrame)
spacerItem = QtWidgets.QSpacerItem(20, 435, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.verticalLayout_3.addItem(spacerItem)
self.displayScrollArea.setWidget(self.scrollAreaWidgetContents)
self.verticalLayout.addWidget(self.displayScrollArea)
self.line = QtWidgets.QFrame(self.centralwidget)
self.line.setMaximumSize(QtCore.QSize(16777215, 1))
self.line.setCursor(QtGui.QCursor(QtCore.Qt.SizeVerCursor))
self.line.setFrameShape(QtWidgets.QFrame.HLine)
self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
self.line.setObjectName("line")
self.verticalLayout.addWidget(self.line)
self.sendFrame = QtWidgets.QFrame(self.centralwidget)
self.sendFrame.setMaximumSize(QtCore.QSize(16777204, 150))
self.sendFrame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.sendFrame.setFrameShadow(QtWidgets.QFrame.Raised)
self.sendFrame.setObjectName("sendFrame")
self.gridLayout = QtWidgets.QGridLayout(self.sendFrame)
self.gridLayout.setContentsMargins(0, 0, 0, 10)
self.gridLayout.setSpacing(0)
self.gridLayout.setObjectName("gridLayout")
self.sendBtn = QtWidgets.QPushButton(self.sendFrame)
self.sendBtn.setObjectName("sendBtn")
self.gridLayout.addWidget(self.sendBtn, 1, 2, 1, 1)
self.sendTextEdit = QtWidgets.QTextEdit(self.sendFrame)
self.sendTextEdit.setObjectName("sendTextEdit")
self.gridLayout.addWidget(self.sendTextEdit, 0, 0, 1, 3)
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.gridLayout.addItem(spacerItem1, 1, 0, 1, 1)
self.verticalLayout.addWidget(self.sendFrame)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.sendBtn.setText(_translate("MainWindow", "发送(S)"))
source_rc.py太大就不贴了,这是对应的source.qrc文件
<RCC>
<qresource prefix="/"/>
<qresource prefix="head">
<file>icons/computer.png</file>
<file>icons/phone.png</file>
</qresource>
<qresource prefix="file">
<file>icons/file.png</file>
<file>icons/more.png</file>
<file>icons/success.png</file>
<file>icons/fail.png</file>
</qresource>
<qresource prefix="demo">
<file>icons/picture.jpg</file>
</qresource>
</RCC>
版权声明:本文为weixin_43069875原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。