删除 QCombobox 以在 window 面板中显示所有数据,供用户一次 select 多个值
Remove QCombobox to show all the data in the window panel for the user to select multiple values at once
我使用了以下代码,它的作用是在组合框中显示一个值列表,但我遇到的困难是每次检查值时,下拉菜单都会关闭。
有没有一种方法可以在主 window 中显示所有菜单而不是下拉菜单作为所有复选框的列表,以便可以一次单击多个值。
以下是代码片段。
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
class CheckableComboBox(QtWidgets.QComboBox):
def __init__(self, parent = None):
super(CheckableComboBox, self).__init__(parent)
self.setView(QtWidgets.QListView(self))
self.view().pressed.connect(self.handleItemPressed)
self.setModel(QtGui.QStandardItemModel(self))
def handleItemPressed(self, index):
item = self.model().itemFromIndex(index)
if item.checkState() == QtCore.Qt.Checked:
item.setCheckState(QtCore.Qt.Unchecked)
else:
item.setCheckState(QtCore.Qt.Checked)
def checkedItems(self):
checkedItems = []
for index in range(self.count()):
item = self.model().item(index)
if item.checkState() == QtCore.Qt.Checked:
checkedItems.append(item)
return checkedItems
class Ui_dialogCreateBatch(object):
def setupUi(self, dialogCreateBatch):
dialogCreateBatch.resize(400, 338)
dialogCreateBatch.setMouseTracking(True)
self.gridLayoutWidget = QtWidgets.QWidget(dialogCreateBatch)
self.gridLayoutWidget.setGeometry(QtCore.QRect(10, 10, 360, 115))
self.gridLayoutWidget.setObjectName("gridLayoutWidget")
self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.cboItemList = CheckableComboBox(self.gridLayoutWidget)
self.cboItemList.setObjectName("cboItemList")
self.gridLayout.addWidget(self.cboItemList, 0, 0, 1, 1)
data = ('item1', 'item2', 'item3')
for index, element in enumerate(data):
self.cboItemList.addItem(element)
item = self.cboItemList.model().item(index, 0)
item.setCheckState(QtCore.Qt.Unchecked)
self.buttonBox = QtWidgets.QDialogButtonBox(dialogCreateBatch)
self.buttonBox.setGeometry(QtCore.QRect(100, 300, 156, 23))
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
self.retranslateUi(dialogCreateBatch)
QtCore.QMetaObject.connectSlotsByName(dialogCreateBatch)
def retranslateUi(self, dialogCreateBatch):
_translate = QtCore.QCoreApplication.translate
dialogCreateBatch.setWindowTitle(_translate("dialogCreateBatch", "Create Item Batch"))
class DialogCreateBatch(QtWidgets.QDialog, Ui_dialogCreateBatch):
def __init__(self, parent=None):
QtWidgets.QDialog.__init__(self, parent)
self.setupUi(self)
self.buttonBox.accepted.connect(self.on_accepted)
self.buttonBox.rejected.connect(self.reject)
def on_accepted(self):
selectedItems = self.cboItemList.checkedItems()
print(selectedItems)
self.accept()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = DialogCreateBatch()
w.show()
sys.exit(app.exec_())
以下代码实现了一个 QDialog,它显示了一个 QListView 模型,该模型具有基于 QStandardItemModel 的可检查项:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class DialogCreateBatch(QtWidgets.QDialog):
def __init__(self, parent=None):
super(DialogCreateBatch, self).__init__(parent)
self.model = QtGui.QStandardItemModel(self)
self.view = QtWidgets.QListView()
self.view.setModel(self.model)
self.button_box = QtWidgets.QDialogButtonBox()
self.button_box.setOrientation(QtCore.Qt.Horizontal)
self.button_box.setStandardButtons(
QtWidgets.QDialogButtonBox.Cancel | QtWidgets.QDialogButtonBox.Ok
)
self.button_box.accepted.connect(self.accept)
self.button_box.rejected.connect(self.reject)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.view)
lay.addWidget(self.button_box)
@property
def items(self):
items = []
for i in range(self.model.rowCount()):
it = self.model.item(i)
items.append(it.text())
return items
@items.setter
def items(self, items):
self.model.clear()
for item in items:
it = QtGui.QStandardItem(item)
it.setCheckable(True)
self.model.appendRow(it)
@property
def checked_items(self):
checked_items = []
for i in range(self.model.rowCount()):
it = self.model.item(i)
if it.data(QtCore.Qt.CheckStateRole) == QtCore.Qt.Checked:
checked_items.append(it.text())
return checked_items
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = DialogCreateBatch()
w.setWindowTitle("Stack Overflow")
w.items = ("item1", "item2", "item3")
if w.exec_() == QtWidgets.QDialog.Accepted:
print(w.checked_items)
我使用了以下代码,它的作用是在组合框中显示一个值列表,但我遇到的困难是每次检查值时,下拉菜单都会关闭。
有没有一种方法可以在主 window 中显示所有菜单而不是下拉菜单作为所有复选框的列表,以便可以一次单击多个值。
以下是代码片段。
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
class CheckableComboBox(QtWidgets.QComboBox):
def __init__(self, parent = None):
super(CheckableComboBox, self).__init__(parent)
self.setView(QtWidgets.QListView(self))
self.view().pressed.connect(self.handleItemPressed)
self.setModel(QtGui.QStandardItemModel(self))
def handleItemPressed(self, index):
item = self.model().itemFromIndex(index)
if item.checkState() == QtCore.Qt.Checked:
item.setCheckState(QtCore.Qt.Unchecked)
else:
item.setCheckState(QtCore.Qt.Checked)
def checkedItems(self):
checkedItems = []
for index in range(self.count()):
item = self.model().item(index)
if item.checkState() == QtCore.Qt.Checked:
checkedItems.append(item)
return checkedItems
class Ui_dialogCreateBatch(object):
def setupUi(self, dialogCreateBatch):
dialogCreateBatch.resize(400, 338)
dialogCreateBatch.setMouseTracking(True)
self.gridLayoutWidget = QtWidgets.QWidget(dialogCreateBatch)
self.gridLayoutWidget.setGeometry(QtCore.QRect(10, 10, 360, 115))
self.gridLayoutWidget.setObjectName("gridLayoutWidget")
self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.cboItemList = CheckableComboBox(self.gridLayoutWidget)
self.cboItemList.setObjectName("cboItemList")
self.gridLayout.addWidget(self.cboItemList, 0, 0, 1, 1)
data = ('item1', 'item2', 'item3')
for index, element in enumerate(data):
self.cboItemList.addItem(element)
item = self.cboItemList.model().item(index, 0)
item.setCheckState(QtCore.Qt.Unchecked)
self.buttonBox = QtWidgets.QDialogButtonBox(dialogCreateBatch)
self.buttonBox.setGeometry(QtCore.QRect(100, 300, 156, 23))
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
self.retranslateUi(dialogCreateBatch)
QtCore.QMetaObject.connectSlotsByName(dialogCreateBatch)
def retranslateUi(self, dialogCreateBatch):
_translate = QtCore.QCoreApplication.translate
dialogCreateBatch.setWindowTitle(_translate("dialogCreateBatch", "Create Item Batch"))
class DialogCreateBatch(QtWidgets.QDialog, Ui_dialogCreateBatch):
def __init__(self, parent=None):
QtWidgets.QDialog.__init__(self, parent)
self.setupUi(self)
self.buttonBox.accepted.connect(self.on_accepted)
self.buttonBox.rejected.connect(self.reject)
def on_accepted(self):
selectedItems = self.cboItemList.checkedItems()
print(selectedItems)
self.accept()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = DialogCreateBatch()
w.show()
sys.exit(app.exec_())
以下代码实现了一个 QDialog,它显示了一个 QListView 模型,该模型具有基于 QStandardItemModel 的可检查项:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class DialogCreateBatch(QtWidgets.QDialog):
def __init__(self, parent=None):
super(DialogCreateBatch, self).__init__(parent)
self.model = QtGui.QStandardItemModel(self)
self.view = QtWidgets.QListView()
self.view.setModel(self.model)
self.button_box = QtWidgets.QDialogButtonBox()
self.button_box.setOrientation(QtCore.Qt.Horizontal)
self.button_box.setStandardButtons(
QtWidgets.QDialogButtonBox.Cancel | QtWidgets.QDialogButtonBox.Ok
)
self.button_box.accepted.connect(self.accept)
self.button_box.rejected.connect(self.reject)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(self.view)
lay.addWidget(self.button_box)
@property
def items(self):
items = []
for i in range(self.model.rowCount()):
it = self.model.item(i)
items.append(it.text())
return items
@items.setter
def items(self, items):
self.model.clear()
for item in items:
it = QtGui.QStandardItem(item)
it.setCheckable(True)
self.model.appendRow(it)
@property
def checked_items(self):
checked_items = []
for i in range(self.model.rowCount()):
it = self.model.item(i)
if it.data(QtCore.Qt.CheckStateRole) == QtCore.Qt.Checked:
checked_items.append(it.text())
return checked_items
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = DialogCreateBatch()
w.setWindowTitle("Stack Overflow")
w.items = ("item1", "item2", "item3")
if w.exec_() == QtWidgets.QDialog.Accepted:
print(w.checked_items)