Bối cảnh: Tôi không thể tìm thấy ví dụ hoạt động đầy đủ của combobox bên trong QTableView
. Vì vậy, tôi đã viết mã này dựa trên một số ví dụ khác contrived hơn ra khỏi đó. Vấn đề là, tuy nhiên, ví dụ này đòi hỏi bạn phải bấm đúp vào combobox trước khi nó được kích hoạt, sau đó bạn phải bấm một lần nữa để thả nó xuống. Nó không thân thiện với người dùng. Nếu tôi thực hiện mô hình không/mô hình xem bằng cách sử dụng QTableWidget
, hộp tổ hợp sẽ giảm xuống trên nhấp chuột đầu tiên.PyQt - ví dụ làm việc đơn giản nhất của combobox bên trong QTableView
Câu hỏi: Ai đó có thể xem điều này và cho tôi biết cần phải làm gì để làm cho nó phản hồi giống như QTableWidget
? Ngoài ra nếu có bất cứ điều gì mà tôi đang làm đó là không cần thiết, xin vui lòng chỉ ra rằng cũng có. Ví dụ, nó là hoàn toàn cần thiết để tham khảo các phong cách ứng dụng?
import sys
from PyQt4 import QtGui, QtCore
rows = "ABCD"
choices = ['apple', 'orange', 'banana']
class Delegate(QtGui.QItemDelegate):
def __init__(self, owner, items):
super(Delegate, self).__init__(owner)
self.items = items
def createEditor(self, parent, option, index):
self.editor = QtGui.QComboBox(parent)
self.editor.addItems(self.items)
return self.editor
def paint(self, painter, option, index):
value = index.data(QtCore.Qt.DisplayRole).toString()
style = QtGui.QApplication.style()
opt = QtGui.QStyleOptionComboBox()
opt.text = str(value)
opt.rect = option.rect
style.drawComplexControl(QtGui.QStyle.CC_ComboBox, opt, painter)
QtGui.QItemDelegate.paint(self, painter, option, index)
def setEditorData(self, editor, index):
value = index.data(QtCore.Qt.DisplayRole).toString()
num = self.items.index(value)
editor.setCurrentIndex(num)
def setModelData(self, editor, model, index):
value = editor.currentText()
model.setData(index, QtCore.Qt.DisplayRole, QtCore.QVariant(value))
def updateEditorGeometry(self, editor, option, index):
editor.setGeometry(option.rect)
class Model(QtCore.QAbstractTableModel):
def __init__(self):
super(Model, self).__init__()
self.table = [[row, choices[0]] for row in rows]
def rowCount(self, index=QtCore.QModelIndex()):
return len(self.table)
def columnCount(self, index=QtCore.QModelIndex()):
return 2
def flags(self, index):
return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
def data(self, index, role):
if role == QtCore.Qt.DisplayRole:
return self.table[index.row()][index.column()]
def setData(self, index, role, value):
if role == QtCore.Qt.DisplayRole:
self.table[index.row()][index.column()] = value
class Main(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Main, self).__init__(parent)
self.model = Model()
self.table = QtGui.QTableView()
self.table.setModel(self.model)
self.table.setItemDelegateForColumn(1, Delegate(self, ["apple", "orange", "banana"]))
self.setCentralWidget(self.table)
self.setWindowTitle('Delegate Test')
self.show()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
main = Main()
app.exec_()
Bạn có thể tìm thấy câu trả lời của tôi để [câu hỏi này] (http://stackoverflow.com/questions/17615997/pyqt-how-to-set-qcombobox-in- a-table-view-using-qitemdelegate) hữu ích. –
Cảm ơn bạn, bây giờ tôi thấy rằng 'paint' override là không cần thiết, và tôi cần' openPersistentEditor'. Nhưng gọi 'openPersistentEditor' dường như đánh bại mục đích của mô hình/xem nếu tôi cần gọi nó từ bên ngoài mô hình. Thêm vào đó, có vẻ như không hiệu quả khi vẽ tất cả các combobox đó khi bạn chỉ có thể hoạt động một lần tại một thời điểm. Có cách nào để loại bỏ yêu cầu nhấp đúp để nó xuất hiện khi lựa chọn ô? – user2120303
Bạn không cần phải gọi nó từ mô hình. Bạn có thể sử dụng một đối tượng khác (ví dụ: dạng xem hoặc biểu mẫu con của bạn) để theo dõi thay đổi mô hình và gọi trình chỉnh sửa nếu cần. Đối với câu hỏi thứ hai, kết nối tín hiệu 'selectionChanged' của' view-> selectionModel() 'vào vị trí của bạn. Trong trình soạn thảo mở khe này trong ô đã chọn và đóng các trình chỉnh sửa trước đó nếu cần. –