select 项并通过鼠标单击从 QlistWidget 更新 QLineedit?

select item and update QLineedit from QlistWidget by Mouse Click?

通过从 QlistWidget 中选择的项目更新 QLineEdit,第一个框按我的意愿更新。但是第二个文本框和第三个文本框,没有被所选项目更新。如果我们为第二个文本框第一个文本框和第二个文本框更新选择项目。而对于第三个,没有反应?如何解决

文件:mouseclick.py

import sys
from mouseclick_source import *

textbox1_item = ["Red", "Green", "Blue", "Brown", "White", "Black", "Grey", 
                  "Dark Red", "Dark Green", "Dark Blue"]
textbox2_item = ["Gold", "Silver", "Bronze", "Copper", "Iron", "Aluminium", 
                "Taitanium"]
textbox3_item = ["Indian Ocean", "Arabian Sea", "Bay of Bengal", "Black Sea", 
                 "Pacific Ocean"]

class Mclick_sample_main(QWidget):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Mouse click Samples")
        self.textbox1 = QLineEdit()
        self.textbox2 = QLineEdit()
        self.textbox3 = QLineEdit()
        self.listbox1 = QListWidget()
        self.listbox2 = QListWidget()

        self.textbox1.setObjectName("textbox1")
        self.textbox2.setObjectName("textbox2")
        self.textbox3.setObjectName("textbox3")
        self.listbox1.setObjectName("listbox1")
        self.listbox2.setObjectName("listbox2")

        vbox = QVBoxLayout(self)
        vbox.addWidget(self.textbox1)
        vbox.addWidget(self.textbox2)
        vbox.addWidget(self.textbox3)
        vbox.addWidget(self.listbox1)

        QApplication.instance().focusChanged.connect(self.on_focusChanged)

    def on_focusChanged(self):
        fwidget = QApplication.focusWidget()
        if fwidget is not None:
            if fwidget.objectName() == "textbox1":
                self.listbox1.clear()
                self.listbox1.addItems(textbox1_item)

                self.getdetails_1 = Sourcefile(self.textbox1, self.listbox1, self.listbox2)
                #self.textbox1.textChanged.connect(self.getdetails_1.func_textbox_textchanged)
                self.listbox1.itemClicked.connect(self.getdetails_1.listbox_clicked)
                return True

            if fwidget.objectName() == "textbox2":
                self.listbox1.clear()
                self.listbox1.addItems(textbox2_item)

                self.getdetails_2 = Sourcefile(self.textbox2, self.listbox1, self.listbox2)
                #self.textbox1.textChanged.connect(self.getdetails_2.func_textbox_textchanged)
                self.listbox1.itemClicked.connect(self.getdetails_2.listbox_clicked)
                return True

            if fwidget.objectName() == "textbox3":
                self.listbox1.clear()
                self.listbox1.addItems(textbox3_item)

                self.getdetails_3 = Sourcefile(self.textbox3, self.listbox1, self.listbox2)
                #self.textbox1.textChanged.connect(self.getdetails_3.func_textbox_textchanged)
                self.listbox1.itemClicked.connect(self.getdetails_3.listbox_clicked)
                return True


def main():
    myapp = QApplication(sys.argv)
    mywin = Mclick_sample_main()
    mywin.show()
    sys.exit(myapp.exec_())


if __name__ == "__main__":
    main()

文件:mouseclick_source.py

from PyQt5.QtWidgets import *

class Sourcefile(QWidget):
    def __init__(self, textbox, listbox1, parent=None):
        super().__init__(listbox2)
        self.tbox1 = textbox
        self.lbox1 = listbox1
            
    def listbox_clicked(self, item):
        self.tbox1.setText(item.text())
        self.tbox1.setFocus()
        return True

问题可能是行 self.tbox1.setFocus() 导致 focusChanged 信号再次发出。 QListWidget 被清除并重新进货,因此没有当前项目文本,文本框设置为空字符串,给人一种“无响应”的感觉。无论如何,我在尝试 运行 代码时遇到分段错误,所以我不得不更改它。

所有信号和插槽连接都可以在主 class 内完成。可以使用 currentTextChanged 信号检测从 QListWidget 中选择一个项目。在 focusChanged 上,保留指向最新 focused-in QLineEdit 的指针。现在,当从列表小部件中选择一个项目时,您可以将文本设置为正确的文本框并重新对其应用焦点。

import sys
from PyQt5.QtWidgets import *

textbox_items = {
    "textbox1": ["Red", "Green", "Blue", "Brown", "White", "Black", "Grey", 
                  "Dark Red", "Dark Green", "Dark Blue"],
    "textbox2": ["Gold", "Silver", "Bronze", "Copper", "Iron", "Aluminium", 
                "Taitanium"],
    "textbox3": ["Indian Ocean", "Arabian Sea", "Bay of Bengal", "Black Sea", 
                 "Pacific Ocean"]
    }

class Mclick_sample_main(QWidget):
    def __init__(self):
        super().__init__()

        self.setWindowTitle("Mouse click Samples")
        self.textbox1 = QLineEdit()
        self.textbox2 = QLineEdit()
        self.textbox3 = QLineEdit()
        self.listbox1 = QListWidget()
        self.listbox1.currentTextChanged[str].connect(self.update_textbox)

        self.textbox1.setObjectName("textbox1")
        self.textbox2.setObjectName("textbox2")
        self.textbox3.setObjectName("textbox3")
        self.listbox1.setObjectName("listbox1")

        vbox = QVBoxLayout(self)
        vbox.addWidget(self.textbox1)
        vbox.addWidget(self.textbox2)
        vbox.addWidget(self.textbox3)
        vbox.addWidget(self.listbox1)

        self.current_textbox = None
        QApplication.instance().focusChanged.connect(self.on_focusChanged)

    def on_focusChanged(self, old, new):
        if isinstance(new, QLineEdit) and new != self.current_textbox:
            self.current_textbox = new
            self.listbox1.clear()
            self.listbox1.addItems(textbox_items[new.objectName()])
                
    def update_textbox(self, text):
        if text:
            self.current_textbox.setText(text)
            self.current_textbox.setFocus()


def main():
    myapp = QApplication(sys.argv)
    mywin = Mclick_sample_main()
    mywin.show()
    sys.exit(myapp.exec_())


if __name__ == "__main__":
    main()