QtableViewとQStandardItemModelを使用してGUIにログを表示し、適切な間隔を維持してログをフィルタリングしています。モデルを作成し、それにデータを挿入しました。フィルタ文字列にQSortFilterProxyModelを使用しました。
self.tableView = QtGui.QTableView(self)
self.model = QtGui.QStandardItemModel(self)
self.proxy = QtGui.QSortFilterProxyModel(self)
self.proxy.setSourceModel(self.model)
self.tableView.setModel(self.proxy)
1秒で、100近くのログが予想され、GUIに表示されます。新しいログが追加されると、ビューは自動スクロールではなく、スライダーは上部にのみ表示されます。ロギングのライブ感はなく、ユーザーは手動で最後までスクロールする必要があります。したがって、これを克服するために、次の構文を使用しました。
self.model.rowsInserted.connect(lambda: QtCore.QTimer.singleShot(5, self.tableView.scrollToBottom))
ログのライブ感を与えますが、スライダーは常に下にあり、上にスクロールして前のログを表示することはできません。スライダーを動かそうとすると、すぐに再び下に下がります。したがって、この構文は私の要件を満たしていません。QTextEditでは、自動スクロールは適切でユーザーフレンドリーです。ここQtableViewで同じシナリオが必要です。QTextEditに似た自動スクロールの代替手段はありますか?
必要な動作を取得するには、前のスクロール位置が一番下にある場合にのみ自動スクロールできます。そうすれば、ユーザーが下からスクロールするたびに、自動スクロールが無効になります。ただし、下にスクロールして戻ると、自動スクロールが再び有効になります。(注:自動スクロールをすばやく再度有効にするには、スクロールバーを右クリックして、コンテキストメニューから[下]を選択します)。
これが簡単なデモです:
from PyQt4 import QtCore, QtGui
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
self.table = QtGui.QTableView(self)
self.model = QtGui.QStandardItemModel(self)
self.table.setModel(self.model)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.table)
self._scroll = True
self.model.rowsAboutToBeInserted.connect(self.beforeInsert)
self.model.rowsInserted.connect(self.afterInsert)
def beforeInsert(self):
vbar = self.table.verticalScrollBar()
self._scroll = vbar.value() == vbar.maximum()
def afterInsert(self):
if self._scroll:
self.table.scrollToBottom()
def addRow(self):
self.model.appendRow([QtGui.QStandardItem(c) for c in 'ABC'])
if __name__ == '__main__':
app = QtGui.QApplication([''])
window = Window()
window.setGeometry(500, 50, 400, 300)
window.show()
timer = QtCore.QTimer()
timer.timeout.connect(window.addRow)
timer.start(200)
app.exec_()
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加