【问题标题】:Accessing to QListWidgetItem from widget inside从小部件内部访问 QListWidgetItem
【发布时间】:2018-02-21 10:41:38
【问题描述】:

我正在尝试弄清楚如何获取作为 QListWidgetItem 插入到 QListWidget 中的 QWidget,以便能够访问它所属的列表,以便它可以执行以下操作:

  • 增加/减少它在列表中的位置
  • 从列表中删除自己
  • 将信息从它自己的类传递给主类中的函数

我的脚本布局是一个 main.py,它是 MainWindow 类所在的位置。 MainWindow 使用从主 ui 文件生成的类。我也有自定义小部件,它是它自己的类。

图形用户界面示例:

相关代码sn-ps:

main.py

from PyQt4.QtGui import QMainWindow, QApplication
from dungeonjournal import Ui_MainWindow
from creature_initiative_object import InitCreatureObject
from os import walk

class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
       super(QMainWindow, self).__init__(parent)
       self.setupUi(self)
       etc......
    def AddToInitiative(self):
        creature = self.comboBoxSelectCharacter.currentText()
        if(creature):
            creatureInfo = ''
            with open("creatures/"+str(creature)+".creature", "r") as f:
                creatureInfo = f.read()
            creatureInfo = creatureInfo.split("|")

            customWidget = InitCreatureObject()
            customWidgetItem = QtGui.QListWidgetItem(self.initiativeList)
            customWidgetItem.setSizeHint(QtCore.QSize(400,50))
            self.initiativeList.addItem(customWidgetItem)
            self.initiativeList.setItemWidget(customWidgetItem, customWidget)
            customWidget.setName(creatureInfo[0])
        return

creature_initiative_object.py

class Ui_InitCreatureObject(object):
    def setupUi(self, InitCreatureObject):
        etc...

class InitCreatureObject(QtGui.QWidget, Ui_InitCreatureObject):
    def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()):
        QtGui.QWidget.__init__(self, parent, f)

        self.setupUi(self)

编辑 1: 再次澄清,我需要能够使用小部件中的按钮来修改其自身在列表中的位置。该列表是主用户界面的一部分。向上箭头、向下箭头、选择和删除按钮是我试图与他们班级之外的事物进行交互的按钮。

他们调用的函数需要能够确定调用的是哪个listItem,能够修改列表。

例如,如果我单击删除,则它需要知道要删除列表中的哪个项目。所以它首先需要知道列表是什么,然后它需要知道它是什么项目。我不确定如何访问占用该列表项的小部件实例。我也不确定如何根据从该列表项的类中按下按钮来获取该列表项。

编辑 2: 根据第一个答案,我尝试将其应用到我的代码中。

main.py 添加了以下函数

def RemoveItem(self):
        cwidget = self.sender().parent()
        item = self.initiativeList.itemAt(cwidget.pos())
        row = self.initiativeList.row(item)
        self.initiativeList.takeItem(row)
        print(row)

creature_initiative_object.py 在 InitCreatureObject 类中添加了以下内容

class InitCreatureObject(QtGui.QWidget, Ui_InitCreatureObject):
    def __init__(self, parent=None, f=QtCore.Qt.WindowFlags()):
        QtGui.QWidget.__init__(self, parent, f)
        self.setupUi(self)
        self.mainwidget = main.MainWindow()
        self.btnRemove.clicked.connect(self.mainwidget.RemoveItem)

项目仍未通过。父对象似乎是正确的,但是当我得到该行时,它总是显示 -1。

【问题讨论】:

  • 更好地解释,当你想要获取小部件(InitCreatureObject)时,解释上下文,你想通过它在列表中的位置来做,或者当你意识到一些事件时
  • @eyllanesc 我已添加到主帖中以尝试进一步澄清它。很难解释,因为这是一个非常小众的问题。
  • 以下行self.mainwidget = main.MainWindow() self.btnRemove.clicked.connect(self.mainwidget.RemoveItem) 正在创建一个新窗口,我建议在main.py 文件中实现我的逻辑

标签: python pyqt pyqt4 qlistwidget qlistwidgetitem


【解决方案1】:

获取QTableWidgetItem 的策略是使用itemAt() 方法,但为此您必须知道QTableWidgetItem 中某个点的位置。

由于主要目标是在发送信号时获取项目,因此使用连接的插槽,因此我建议将所有信号连接到该插槽。鉴于上述情况,采取以下步骤:

  • 通过sender()获取发出信号的对象。
  • 获取发件人parent(),因为这将是与项目一起添加到QListWidget() 的自定义小部件。
  • 通过pos()获取自定义小部件的位置,这是itemAt()方法中应该使用的位置。
  • 然后你会得到按钮的文本或一些参数,告诉我任务知道你想要做什么。

上面可以这样实现:

def someSlot(self):
    p = self.sender().parent()
    it = self.lw.itemAt(p.pos())
    text = self.sender().text()
    if text == "task1":
        do task1
    elif text == "task2":
        do task2    

综上所述,提出如下示例:

class CustomWidget(QWidget):
    def __init__(self, text, parent=None):
        QWidget.__init__(self, parent)
        self.setLayout(QHBoxLayout())
        self.buttons = []
        vb = QVBoxLayout()
        self.layout().addLayout(vb)
        self.btnTask1 = QPushButton("task1")
        self.btnTask2 = QPushButton("task2")

        vb.addWidget(self.btnTask1)
        vb.addWidget(self.btnTask2)

        self.buttons.append(self.btnTask1)
        self.buttons.append(self.btnTask2)

        self.btnTask3 = QPushButton("task3")
        self.btnTask4 = QPushButton("task4")
        self.btnTask5 = QPushButton("task5")
        self.btnTask6 = QPushButton("task6")
        self.layout().addWidget(self.btnTask3)
        self.layout().addWidget(self.btnTask4)
        self.layout().addWidget(self.btnTask5)
        self.layout().addWidget(self.btnTask6)

        self.buttons.append(self.btnTask3)
        self.buttons.append(self.btnTask4)
        self.buttons.append(self.btnTask5)
        self.buttons.append(self.btnTask6)


class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.lw = QListWidget(self)
        self.setCentralWidget(self.lw)
        for i in range(5):
            cw = CustomWidget("{}".format(i))
            for btn in cw.buttons:
                btn.clicked.connect(self.onClicked)

            item = QListWidgetItem(self.lw)
            item.setSizeHint(QSize(400, 80))
            self.lw.addItem(item)
            self.lw.setItemWidget(item, cw)

    def onClicked(self):
        p = self.sender().parent()
        it = self.lw.itemAt(p.pos())
        row = self.lw.row(it)
        text = self.sender().text()
        print("item {}, row {}, btn: {}".format(it, row, text))
        #if text == "task1":
        # do task1
        #elif text == "task2":
        # do task2    



if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

在你的情况下:

class MainWindow(QMainWindow, Ui_MainWindow):
    [...]
    def AddToInitiative(self):
        [...]
        customWidget = InitCreatureObject()
        customWidget.btnRemove.clicked.connect(self.RemoveItem)
        # ^^^^^
        [...]
    def RemoveItem(self):
        cwidget = self.sender().parent()
        item = self.initiativeList.itemAt(cwidget.pos())
        row = self.initiativeList.row(item)
        self.initiativeList.takeItem(row)
        print(row)

【讨论】:

  • 我仍在努力让它与您的答案一起使用。问题是您的示例没有使用与我的脚本相同的逻辑。我的小部件是在按下按钮时动态添加的,每个按钮都需要做一些不同的事情,因此链接到每个按钮的 onClicked 对我没有任何作用。它背后的想法应该使我能够获得该项目,但事实并非如此。每当我尝试访问该项目时,无论我按下哪个小部件的按钮,行数都是 -1。
  • 我知道每个按钮执行不同的任务,在那个地方打印带有该信息的文本,您可以知道要执行什么任务,如果您在实施我的解决方案时遇到问题,只需分享您的代码,我会做它。
  • 感谢您的提议和帮助,但我想我现在只能坐以待毙。如果我不明白它是如何工作的,那么我稍后会遇到该程序的问题。我测试了您放置的代码并且您的代码可以自行运行我只是不知道如何实现它。发件人和发件人的父母可能是我的问题,因为它与您的示例不同,都是嵌套的。
  • 检查我的答案,我已针对您的特定情况进行了更新。 :P
  • 效果很好,非常感谢。通过这个,我学到了很多关于 PyQt 和类交互的知识。额外的解释让我更清楚一些模糊的地方,特别是按钮文本的使用。
猜你喜欢
  • 2022-11-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-04
  • 1970-01-01
  • 1970-01-01
  • 2018-04-12
  • 1970-01-01
  • 2021-06-10
相关资源
最近更新 更多