1

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

列表框

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
4

2 回答 2

2

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

输入框.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_() 方法,如果调用accept 或reject,则返回一个代码,并据此必须获取并添加数据。另一方面,不要使用全局变量,因为它们在调试时很头疼。

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 ,因为另一个答案表明您可以将相同的对话框用于其他目的。

于 2018-11-20T17:54:48.047 回答
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_form或 上的插槽list_widget。或者在 中,input_box您可以通过其父级导航到list_widget. 但我认为我的方法简单明了。

于 2018-11-20T17:57:59.437 回答