PyQt4:如何实现QListWidget列表消息水平(从右到左)滚动?
实现PyQt4列表项文本从右到左滚动显示的解决方案
嘿,你的代码没法实现滚动是因为QListWidget默认就没带文本自动滚动的功能~ 要实现从右到左的跑马灯效果,咱们可以用两种简单的方法来修改,下面给你详细说:
方法一:用定时器循环更新文本(简单易上手)
这种方法通过定时修改列表项显示的文本内容,模拟滚动效果,代码改动小,容易理解:
from PyQt4 import QtCore, QtGui from PyQt4.QtGui import * from PyQt4.QtCore import * class MyWindow(QMainWindow): def __init__(self, parent=None): super(MyWindow, self).__init__(parent) self.centralwidget = QWidget(self) self.setCentralWidget(self.centralwidget) self.my_list = QtGui.QListWidget(self.centralwidget) self.my_list.setObjectName("my_list") # 存储完整的滚动文本 self.full_scroll_text = "Hello this is scroll message in pyqt4" # 滚动起始索引,控制从右到左的滚动方向 self.scroll_index = len(self.full_scroll_text) # 初始化列表项 self.my_list.addItem(self.full_scroll_text) item = self.my_list.item(0) self.my_list.setItemSelected(item, True) # 定时器:每隔200毫秒更新一次文本 self.scroll_timer = QTimer(self) self.scroll_timer.timeout.connect(self.update_scroll_content) self.scroll_timer.start(200) def update_scroll_content(self): # 索引递减,实现从右到左滚动 self.scroll_index -= 1 if self.scroll_index < 0: self.scroll_index = len(self.full_scroll_text) # 构造滚动显示的文本:截取当前索引到末尾的部分,拼接开头部分 display_text = self.full_scroll_text[self.scroll_index:] + " " + self.full_scroll_text[:self.scroll_index] # 更新列表项文本 self.my_list.item(0).setText(display_text) if __name__ == "__main__": import sys app = QApplication(sys.argv) window = MyWindow() window.show() sys.exit(app.exec_())
代码说明:
- 我们用
full_scroll_text存完整的要滚动的文本,scroll_index控制滚动的起始位置 - 定时器每隔200毫秒触发一次更新,通过递减索引让文本从右往左滚动
- 每次更新时,把文本从当前索引截断,再把前面的部分拼到后面,实现循环滚动的效果
方法二:自定义绘制委托(更优雅,不修改原始文本)
如果不想频繁修改文本内容,可以自定义一个项委托,在绘制文本的时候处理滚动逻辑,这种方法更灵活:
from PyQt4 import QtCore, QtGui from PyQt4.QtGui import * from PyQt4.QtCore import * class ScrollItemDelegate(QStyledItemDelegate): def __init__(self, parent=None): super(ScrollItemDelegate, self).__init__(parent) self.scroll_offset = 0 # 定时器控制滚动速度 self.scroll_timer = QTimer(self) self.scroll_timer.timeout.connect(self.update_scroll_offset) self.scroll_timer.start(200) def update_scroll_offset(self): self.scroll_offset += 1 # 触发列表视图重绘 self.parent().viewport().update() def paint(self, painter, option, index): text = index.data(Qt.DisplayRole).toString() if not text: super().paint(painter, option, index) return painter.save() text_width = painter.fontMetrics().width(text) # 如果文本长度小于等于列表项宽度,直接正常绘制 if text_width <= option.rect.width(): painter.drawText(option.rect, Qt.AlignLeft | Qt.AlignVCenter, text) painter.restore() return # 计算滚动偏移,实现从右到左滚动 offset = self.scroll_offset % text_width # 绘制偏移后的文本 draw_rect = option.rect.adjusted(offset, 0, offset, 0) painter.drawText(draw_rect, Qt.AlignLeft | Qt.AlignVCenter, text) # 当文本移出左侧区域时,在右侧补绘剩余部分 if offset > 0: wrap_rect = option.rect.adjusted(offset - text_width, 0, offset - text_width, 0) painter.drawText(wrap_rect, Qt.AlignLeft | Qt.AlignVCenter, text) painter.restore() class MyWindow(QMainWindow): def __init__(self, parent=None): super(MyWindow, self).__init__(parent) self.centralwidget = QWidget(self) self.setCentralWidget(self.centralwidget) self.my_list = QtGui.QListWidget(self.centralwidget) self.my_list.setObjectName("my_list") # 设置自定义委托 self.my_list.setItemDelegate(ScrollItemDelegate(self.my_list)) # 添加要滚动的文本 self.my_list.addItem("Hello this is scroll message in pyqt4") item = self.my_list.item(0) self.my_list.setItemSelected(item, True) if __name__ == "__main__": import sys app = QApplication(sys.argv) window = MyWindow() window.show() sys.exit(app.exec_())
代码说明:
- 自定义的
ScrollItemDelegate重写了paint方法,负责绘制滚动的文本 - 定时器定时更新滚动偏移量,触发重绘
- 绘制时会判断文本长度,如果超过列表项宽度,就通过偏移量实现从右到左的滚动,还会处理文本循环的情况
另外,你原来的代码里有个小错误:self.room_no.setObjectName(_fromUtf8("my_list"))应该改成self.my_list.setObjectName(_fromUtf8("my_list"))(或者直接用字符串,PyQt4也支持),不然对象名设置错了哦~
内容的提问来源于stack exchange,提问作者Akash Nil
相关产品推荐
相关产品推荐

