如果调用 setTabText(),列表视图不会刷新
是的,我知道这听起来很疯狂。但情况是这样的。
我编写了一个最小的代码来重现该错误。该代码使用 QTabWidget
创建主窗口,该窗口又包含一个带有 QListView
的选项卡和一个按钮。列表视图连接到QAbstractListModel
。最初,列表模型包含空列表。如果用户单击按钮,则会填充 3 个元素并发出相应的信号。在此信号上,选项卡小部件会发出带有新标题的信号,该信号由 QMainWindow 捕获并用于更改选项卡标题。
所以,问题是,如果我使用这个新标题调用 setTabText()
,列表视图将保持为空,直到我单击它(然后新项目立即出现)。如果我在 setWindowTitle()
中使用新标题,则按下按钮后新项目会立即出现在列表视图中。我是否做错了什么,或者 QTabWidget (或 Python 映射)中存在一些错误?
代码如下:
from PyQt4 import QtGui, QtCore
import sys
class MainWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.setWindowTitle("Test")
self._tabbar = QtGui.QTabWidget()
self.setCentralWidget(self._tabbar)
tab = SearchWindow(self)
tab.titleChanged.connect(self._refreshTabTitle)
self._tabbar.addTab(tab, "Initial title")
def _refreshTabTitle(self, title):
# if line 1 is commented - no bug, if line 2 is commented - bug exists
self._tabbar.setTabText(0, title) # line 1
#self.setWindowTitle(title) # line 2
class SearchWindow(QtGui.QSplitter):
titleChanged = QtCore.pyqtSignal(str)
def __init__(self, parent):
QtGui.QSplitter.__init__(self, QtCore.Qt.Vertical, parent)
results_model = ResultsModel(self)
results_view = QtGui.QListView()
results_view.setModel(results_model)
self.addWidget(results_view)
search_button = QtGui.QPushButton(">>")
search_button.clicked.connect(results_model.refreshResults)
self.addWidget(search_button)
results_model.searchFinished.connect(self._refreshTitle)
def _refreshTitle(self):
self.titleChanged.emit("New title")
class ResultsModel(QtCore.QAbstractListModel):
searchFinished = QtCore.pyqtSignal()
def __init__(self, parent):
QtCore.QAbstractListModel.__init__(self, parent)
self._results = []
def rowCount(self, parent):
return len(self._results)
def data(self, index, role=QtCore.Qt.DisplayRole):
if not index.isValid():
return None
elif index.row() = len(self._results):
return None
elif role == QtCore.Qt.DisplayRole:
return self._results[index.row()]
def refreshResults(self):
self._results = ['result1', 'result2', 'result3']
self.reset()
self.searchFinished.emit()
app = QtGui.QApplication(sys.argv)
wnd = MainWindow()
wnd.show()
sys.exit(app.exec_())
在Mac OS 10.6.2,Qt SDK 2009.04(4.5),pyQt 4.6.1(也许这就是问题所在,我需要使用4.5?),Python 3.1上测试。
Yes, I know this sounds crazy. But here's the situation.
I composed a minimal code reproducing the bug. The code creates main window with QTabWidget
, which, in turn, has one tab with QListView
and a button. List view is connected to QAbstractListModel
. Initially, list model contains empty list. If user clicks on a button, it is populated with 3 elements and corresponding signal is emitted. On this signal, tab widget emits a signal with new title, which is caught by QMainWindow
and used to change tab title.
So, the problem is, if I call setTabText()
with this new title, list view remains empty until I click on it (then new items instantly appear). If I use new title in setWindowTitle()
instead, new items appear in list view right after pressing the button. Am I doing something wrong, or is there some bug in QTabWidget
(or Python mapping)?
Code is the following:
from PyQt4 import QtGui, QtCore
import sys
class MainWindow(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.setWindowTitle("Test")
self._tabbar = QtGui.QTabWidget()
self.setCentralWidget(self._tabbar)
tab = SearchWindow(self)
tab.titleChanged.connect(self._refreshTabTitle)
self._tabbar.addTab(tab, "Initial title")
def _refreshTabTitle(self, title):
# if line 1 is commented - no bug, if line 2 is commented - bug exists
self._tabbar.setTabText(0, title) # line 1
#self.setWindowTitle(title) # line 2
class SearchWindow(QtGui.QSplitter):
titleChanged = QtCore.pyqtSignal(str)
def __init__(self, parent):
QtGui.QSplitter.__init__(self, QtCore.Qt.Vertical, parent)
results_model = ResultsModel(self)
results_view = QtGui.QListView()
results_view.setModel(results_model)
self.addWidget(results_view)
search_button = QtGui.QPushButton(">>")
search_button.clicked.connect(results_model.refreshResults)
self.addWidget(search_button)
results_model.searchFinished.connect(self._refreshTitle)
def _refreshTitle(self):
self.titleChanged.emit("New title")
class ResultsModel(QtCore.QAbstractListModel):
searchFinished = QtCore.pyqtSignal()
def __init__(self, parent):
QtCore.QAbstractListModel.__init__(self, parent)
self._results = []
def rowCount(self, parent):
return len(self._results)
def data(self, index, role=QtCore.Qt.DisplayRole):
if not index.isValid():
return None
elif index.row() = len(self._results):
return None
elif role == QtCore.Qt.DisplayRole:
return self._results[index.row()]
def refreshResults(self):
self._results = ['result1', 'result2', 'result3']
self.reset()
self.searchFinished.emit()
app = QtGui.QApplication(sys.argv)
wnd = MainWindow()
wnd.show()
sys.exit(app.exec_())
Tested on Mac OS 10.6.2, Qt SDK 2009.04 (4.5), pyQt 4.6.1 (maybe this is the problem and I need to use 4.5?), Python 3.1.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
无法使用 Linux、Qt 4.5.3、pyQt 4.5.4、python 2.5.2 重现您的问题。
我想这绝对是版本/平台相关的。您应该在 MacOS 上尝试 Qt 4.5.3 + pyQt 4.5.4 + python 2.5.2。如果您可以重现该问题,则它更像是 MacOS qt 端口中的错误。如果不能,您应该在 Windows 或 Linux 下尝试更新的 qt 版本。
Could not reproduce your problem using Linux, Qt 4.5.3, pyQt 4.5.4, python 2.5.2.
I guess this is definitely version/platform-dependent. You should try Qt 4.5.3 + pyQt 4.5.4 + python 2.5.2 on MacOS. If you can reproduce the problem, it is more like a bug in MacOS qt port. If you can't you should try newer qt versions under Windows or Linux.