当前位置:编程学习 > wap >>

用 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 自动折行这样的效果……只能再考虑考虑。 --------------------编程问答--------------------
引用 2 楼 maogou4260 的回复:
    def resizeEvent(self, e):
        self.fitInView(0, 0, self.scene.width(), self.scene.height())


我试了这种方法,却发现这只能机械的伸缩图形,而不能实现 TextLayoutItem 自动折行这样的效果……只能再考虑考虑。

这个还要自己写代码。因为如果只考虑自动折行,那么可以考虑使用QTextEdit控件。自己绘制背景即可。 --------------------编程问答--------------------
引用 3 楼 jiangcaiyang123 的回复:
Quote: 引用 2 楼 maogou4260 的回复:

    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
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,