PyQt:将用户输入添加到列表中

时间:2018-11-20 17:34:17

标签: python pyqt pyqt4

我正在尝试创建一个列表框,用户可以在其中输入更多项目到列表中。我有一个带有添加按钮的列表框。添加按钮将打开一个用户输入框,它将指示用户输入值。但是,在将用户输入的值传递到列表中时,我遇到了问题。任何建议都会有所帮助。下面是我的代码:

列表框

from input_box import *

class list_form(QtGui.QWidget):

    def __init__(self,list_of_items,open_text,parent= None):
        super(list_form, self).__init__()

        global output_path
        output_path = output_path_i

        grid = QtGui.QGridLayout()
        grid.setSpacing(10)
        self.widget = QtGui.QWidget()

        self.layout = QtGui.QGridLayout(self.widget)
        open_message = QtGui.QLabel(open_text)
        grid.addWidget(open_message,0,0,2,4)

        self.lst = QtGui.QListWidget()
        grid.addWidget(self.lst,3, 0,1,4)

        for i in list_of_items:
            self.lst.addItem(str(i))

        self.setLayout(grid)

        add = QtGui.QPushButton('Add')
        grid.addWidget(add,50,0)
        add.clicked.connect(self.add_button)

    def add_button(self):
        self.input_box = input_box()
        self.input_box.setWindowTitle("Window 2")
        self.input_box.show()

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    window = list_form(list(xrange(100)),"List of Values")
    window.setWindowTitle('Window 1')
    window.show()
    sip.setdestroyonexit(False)
    sys.exit(app.exec_())

输入框

import sys
from PyQt4 import QtCore, QtGui
import sip

class input_box(QtGui.QWidget):

    def __init__(self,parent= None):
        super(input_box, self).__init__()

        grid = QtGui.QGridLayout()
        grid.setSpacing(10)
        self.widget = QtGui.QWidget()

        self.layout = QtGui.QGridLayout(self.widget)
        open_message = QtGui.QLabel("Enter Value:")
        grid.addWidget(open_message,0,0,2,3)

        self.txt = QtGui.QLineEdit()
        grid.addWidget(self.txt,2, 0,1,2)

        self.setLayout(grid)

        save = QtGui.QPushButton('Save')
        grid.addWidget(save,50,0)
        a = save.clicked.connect(self.save)
        save.clicked.connect(self.close)

        cancel = QtGui.QPushButton('Cancel')
        grid.addWidget(cancel,50,1)
        cancel.clicked.connect(self.close)


    def save(self):
        value = self.txt.text()
        return value

2 个答案:

答案 0 :(得分:2)

如果要从窗口获取数据,则应使用QDialog而不是QWidget,将单击的保存和取消信号分别连接到接受和拒绝插槽:

input_box.py

from PyQt4 import QtCore, QtGui

class Input_Box(QtGui.QDialog):
    def __init__(self,parent= None):
        super(Input_Box, self).__init__(parent)

        open_message = QtGui.QLabel("Enter Value:")
        self.txt = QtGui.QLineEdit()
        save = QtGui.QPushButton('Save', clicked=self.accept)
        cancel = QtGui.QPushButton('Cancel', clicked=self.reject)

        grid = QtGui.QGridLayout(self)
        grid.setSpacing(10)
        grid.addWidget(open_message, 0, 0)
        grid.addWidget(self.txt, 1, 0, 1, 2)
        grid.addWidget(save, 2, 0)
        grid.addWidget(cancel, 2, 1)
        self.setFixedSize(self.sizeHint())

    def save(self):
        value = self.txt.text()
        return value

然后,您使用exec_()方法返回一个代码(如果该代码被称为接受或拒绝),并根据该代码必须获取并添加数据。另一方面,请勿使用全局变量,因为它们在调试时很麻烦。

from PyQt4 import QtCore, QtGui
from input_box import Input_Box

class list_form(QtGui.QWidget):
    def __init__(self,list_of_items,open_text,parent= None):
        super(list_form, self).__init__()

        open_message = QtGui.QLabel(open_text)
        self.lst = QtGui.QListWidget()
        self.lst.addItems([str(i) for i in list_of_items])
        add = QtGui.QPushButton('Add', clicked=self.add_button)
        grid = QtGui.QGridLayout(self)
        grid.setSpacing(10)
        grid.addWidget(open_message)
        grid.addWidget(self.lst)
        grid.addWidget(add)

    @QtCore.pyqtSlot()
    def add_button(self):
        input_box = Input_Box()
        input_box.setWindowTitle("Window 2")
        if input_box.exec_() == QtGui.QDialog.Accepted:
            val = input_box.save()
            it = QtGui.QListWidgetItem(val)
            self.lst.addItem(it)
            self.lst.scrollToItem(it)

if __name__ == "__main__":
    import sys
    import sip
    app = QtGui.QApplication(sys.argv)
    window = list_form(list(range(100)),"List of Values")
    window.setWindowTitle('Window 1')
    window.show()
    sip.setdestroyonexit(False)
    sys.exit(app.exec_())

使用QDialog的优点是类之间的解耦,例如,无需传递QListWidget,因为另一个答案表明可以将同一对话框用于其他目的。

答案 1 :(得分:0)

您需要安排按下保存按钮时的操作,以将信息传递回列表小部件。有多种方法可以执行此操作,但是仅返回数据将无法完成。

这是将起作用的示例,尽管其他方法也是可行的。

更改input_box构造函数,使其保留对期望的列表窗口小部件的引用:

class input_box(QtGui.QWidget):

    def __init__(self, list_widget, parent= None):
        super(input_box, self).__init__()
        self.list_widget = list_widget
        ...

更改对构造函数的调用以提供该信息:

    def add_button(self):
        self.input_box = input_box(self.lst)
        self.input_box.setWindowTitle("Window 2")
        self.input_box.show()

然后在save方法中使用该信息将其添加到列表小部件:

    def save(self):
        value = self.txt.text()
        self.list_widget.addItem(value)

宾果!

另一种方法可能是安排input_box发出其中包含新值的信号,并将其连接到list_formlist_widget上的插槽。或者在input_box中,您可以通过其父级导航到list_widget。但是我认为我很简单直接。