我有一个带有QListWidget的GUI,它没有任何条目。使用“添加”按钮添加条目。我的问题是,当您编辑列表项的文本时,如果在按下Enter键或单击鼠标键之前再次单击添加按钮,则会删除您输入的文本(请参阅gif以供参考)
另外,还有一个gif显示代码可以正常工作:
问题是它不会保存您每次击键输入的内容。而是等到您完成操作并更改选择或按Enter键。
有人可以建议解决此问题的方法吗?
代码:
我在GUI类的init函数中声明了以下信号:
self.w_client_list.itemChanged.connect(self.edit_client_name)
self.w_client_list.itemSelectionChanged.connect(self.switching_clients)
self.b_add_client.clicked.connect(self.add_client)
这些是信号连接到的插槽功能:
def get_index(self):
"""Gets index number of selected client for client details functions"""
for i in range(self.w_client_list.count()):
if self.w_client_list.item(i).isSelected():
index = i
return index
index = None
return index
@Slot()
def switching_clients(self):
index = self.get_index()
if index == None:
self.l_email.clear()
self.c_main_email.setCheckState(Qt.Unchecked)
self.c_secondary_email.setCheckState(Qt.Unchecked)
self.w_phone.clear()
self.l_preferred_name.clear()
self.w_title.setCurrentText('Mr')
else:
# Email
self.l_email.setText(self.client.individual[index]['email'][0])
self.c_main_email.setChecked(self.client.individual[index]['email'][1])
self.c_secondary_email.setChecked(self.client.individual[index]['email'][2])
# Phone
self.update_phone_list()
# Preferred Name
self.l_preferred_name.setText(self.client.individual[index]['preferred_name'])
# Title
self.w_title.setCurrentText(self.client.individual[index]['title'])
@Slot()
def edit_client_name(self):
index = self.get_index()
self.client.individual[index]['full_name'] = self.w_client_list.item(index).text().strip()
self.switching_clients()
@Slot()
def add_client(self):
self.client.individual.append({'title': 'Mr', 'first_name': '', 'middle_name': '', 'last_name': '',
'full_name': 'Enter full name',
'preferred_name': '', 'salutation': '', 'postal_salutation': '',
'email': ['', 0, 0], 'address': [], 'phone': [],
'preferred_name_connected': True})
self.update_client_list() # Updates the client form to show new address row
def update_client_list(self):
self.w_client_list.clear()
client_list = []
for client in self.client.individual:
item = QtWidgets.QListWidgetItem()
item.setText(client['full_name'])
item.setFlags(
QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled)
self.w_client_list.addItem(item)
item.setSelected(True)
答案 0 :(得分:2)
您可以通过setting the focus policy中的按钮NoFocus
来解决此问题。这使项目编辑器在单击按钮时保持打开状态(因为它们不会占用焦点)。然后,可以使用列表小部件的isPersistentEditorOpen方法来防止用户仍在编辑时进行不必要的操作。
更新:
如果要在添加新项目时提交当前编辑,则可以只调用列表小部件上的setFocus
(因为该按钮不会占据焦点)。这也意味着不再需要按照上面的建议检查项目编辑器是否打开。
这是基于您的代码的有效演示:
import sys
from PyQt5 import QtCore, QtWidgets
class Client:
individual = []
class Window(QtWidgets.QWidget):
def __init__(self):
super(Window, self).__init__()
self.client = Client()
self.b_add_client = QtWidgets.QPushButton('Add')
self.b_add_client.setFocusPolicy(QtCore.Qt.NoFocus)
self.w_client_list = QtWidgets.QListWidget()
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.w_client_list)
layout.addWidget(self.b_add_client)
self.w_client_list.itemChanged.connect(self.edit_client_name)
self.b_add_client.clicked.connect(self.add_client)
def get_index(self):
selection = self.w_client_list.selectedItems()
if selection:
return self.w_client_list.indexFromItem(selection[0]).row()
def switching_clients(self):
pass
def edit_client_name(self):
index = self.get_index()
if index is not None:
text = self.w_client_list.item(index).text().strip()
if text:
self.client.individual[index]['full_name'] = text
self.switching_clients()
def add_client(self):
self.w_client_list.setFocus()
self.client.individual.append({
'title': 'Mr', 'first_name': '', 'middle_name': '',
'last_name': '', 'full_name': 'Enter full name',
'preferred_name': '', 'salutation': '',
'postal_salutation': '', 'email': ['', 0, 0],
'address': [], 'phone': [],
'preferred_name_connected': True,
})
self.update_client_list()
def update_client_list(self):
if len(self.client.individual):
self.w_client_list.clear()
for client in self.client.individual:
item = QtWidgets.QListWidgetItem()
item.setText(client['full_name'])
item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable)
self.w_client_list.addItem(item)
item.setSelected(True)
self.w_client_list.editItem(item)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = Window()
window.setGeometry(600, 100, 300, 200)
window.show()
sys.exit(app.exec_())
答案 1 :(得分:0)
我要做的是,当用户单击“添加”时,程序首先通过比较“旧”字符串来验证条目是否已更改。 和新的。如果是这样,它将保存新的字符串并将其设置为小部件。否则,它将仅添加新条目。我希望这可以引导您找到解决方案。
答案 2 :(得分:0)
当前行为是预期行为。
您已正确识别出罪魁祸首:用户需要进行编辑更改,而中断编辑过程将取消该更改。如果您希望立即应用更改,则需要一个实现替代行为的自定义委托。 (有关自定义委托的工作方式,请参见this example in Qt docs。
请注意,尽管如此,更改基本的UI行为还是被忽略了。您的应用程序看起来将与其他任何应用程序一样,但是在行为上与其他应用程序有所不同。在UI世界中,通常 consistency 为王。自定义此类行为也会产生无法预料的副作用,尤其是在您针对多个平台的情况下。而且还需要维护很多额外的代码。