用 QGraphics 框架代替 QWidget 重新实现微博时间线的相关问题
我正在开发一个基于 PyQt 简单的微博客户端。最初尝试过 QML,但由于 QML 存在许多问题,便放弃了。最后,使用 QWidget 顺利开发完成。但问题显而易见,如此多的对象和 Widget,消耗大量内存和 CPU 资源。程序的很多地方,还使用了 Widget 套 Widget 的方法;以及 Python 本身不具有性能优势,更加剧了这个问题。在普通配置机器上,微博时间线向下阅读几页后,反映就会开始变得迟缓。
因此,我在看了 QGraphics 的 40000Chips 这个 Demo 后,决定使用 QGraphics 重新实现微博时间线。
但是,由于 QGraphics 精简了大量 QWidget 的特性,所以替代存在很多问题。现阶段的问题,以布局管理为首。QWidget 提供的 QVBoxLayout,QBoxLayout 等基本布局,到了 QGraphics 里都不见了。我使用 QGraphicsLinearLayout 可以找回原有的布局特性,但是这种布局,不能实现管理 Item 的大小。
例如这段删减过的代码:
class TextLayoutItem(QtGui.QGraphicsLayoutItem):
def __init__(self, text, parent=None):
super(TextLayoutItem, self).__init__(parent)
self.textItem = QtGui.QGraphicsTextItem()
self.textItem.setHtml(text)
self.setGraphicsItem(self.textItem)
def sizeHint(self, which, constraint=QtCore.QSizeF()):
return self.textItem.boundingRect().size()
def setGeometry(self, rect):
self.textItem.setPos(rect.topLeft())
class MyView(QtGui.QGraphicsView):
def __init__(self, parent=None):
super(MyView, self).__init__(parent)
mainLayout = QtGui.QGraphicsLinearLayout()
mainLayout.setSpacing(0)
text = TextLayoutItem("This is a very looooooooooooooooooooong string.")
mainLayout.addItem(text)
mainLayout.setAlignment(text, Qt.AlignCenter)
self.mainWidget = QtGui.QGraphicsWidget()
self.mainWidget.setLayout(mainLayout)
self.scene = QtGui.QGraphicsScene(self.mainWidget)
self.scene.addItem(self.mainWidget)
self.setScene(self.scene)
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.layout = QtGui.QVBoxLayout()
self.view = MyView()
self.view.show()
self.layout.addWidget(self.view)
self.setLayout(self.layout)
if __name__ == "__main__":
App = QtGui.QApplication(sys.argv)
main = MainWindow()
exit(App.exec())
这样,虽然我有了一个基本的布局,但是却不能实现调整窗体大小后,TextLayoutItem 会随着窗体宽度的变化而自动折行。QGraphicsScene 的大小似乎也是固定的,调整窗体大小后,只会出现滚动条。
对于这个问题,有什么解决方法吗? pyqt python QGraphics --------------------编程问答-------------------- 重写你MyView的resizeEvent()其中改变scene的大小。 --------------------编程问答--------------------
def resizeEvent(self, e):
self.fitInView(0, 0, self.scene.width(), self.scene.height())
我试了这种方法,却发现这只能机械的伸缩图形,而不能实现 TextLayoutItem 自动折行这样的效果……只能再考虑考虑。 --------------------编程问答--------------------
这个还要自己写代码。因为如果只考虑自动折行,那么可以考虑使用QTextEdit控件。自己绘制背景即可。 --------------------编程问答--------------------
就是因为 QWidget 太重了,不适合程序,所以改用 QGraphics 框架。现在在 QGraphics 里面用 ProxyWidget 套 QWidget,估计程序会更重…… --------------------编程问答-------------------- 用QWebkit来显示,会简单很多。 --------------------编程问答-------------------- QGraphicsView Framework的显示效率相对QWidget高,但是可用的item确实少。或许你可以考虑自己写一个显示文字的item:) --------------------编程问答-------------------- 我觉得如果有需要,自己写一个QGraphicsView Framework下的TextEdit物件是可行的。而且你这个只是用于微博,每条微博的字数只有百来字,计算换行的效率应该完全可以接受。而且可以看看QTextEdit的源代码,看能否查到它计算自动换行的思路。我自己写过QGraphicsView下的LineEdit,实现了一些必要的LineEdit功能,对我来说完全够用。
所以,考虑一下自己写一个LineEdit吧:)
补充:移动开发 , Qt