繁体   English   中英

pyqt信号未在QAbstractTableModel中发出

[英]pyqt signal not emitted in QAbstractTableModel

因此,我正在编写一个应用程序,并将QTableViewQAbstractTableModel一起使用来显示我的数据。 在每一行中,复选框都放置在第一列中,当选中或取消选中它时,我希望将pyqtsignal CheckBoxValue发出给MyTable 但是似乎未调用MyTable连接的函数self.checkboxchecked 尽管我曾经多次使用pyqtSignal,没有任何问题,但我一直呆在这里,无法解决它。

谢谢大家花时间解决我的问题!

import operator  # used for sorting
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import QtGui, QtCore

class MyTable(QWidget):
    Checkboxcheckvalue = pyqtSignal(bool)
    Rowselected = pyqtSignal(int)
    doubleClicked = pyqtSignal(int)
    def __init__(self,  *args):
        QWidget.__init__(self, *args)
        # setGeometry(x_pos, y_pos, width, height)
        # self.setGeometry(70, 150, 1326, 582)
        self.dataList = []
        self.header = []
        self.currentrow = []
        self.setWindowTitle("Click on the header to sort table")

        self.table_model = MyTableModel(self, self.dataList, self.header)
        self.table_view = QTableView()
        #self.table_view.setSelectionMode(QAbstractItemView.SingleSelection)
        self.table_view.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)
        self.table_view.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
        # bind cell click to a method reference
        self.table_view.clicked.connect(self.showSelection)
        self.table_view.clicked.connect(self.selectRow)

        self.table_view.doubleClicked.connect(self.doubleclickedaction)

        self.table_model.CheckBoxValue.connect(self.checkboxchecked)




        self.table_view.setModel(self.table_model)
        # enable sorting
        self.table_view.setSortingEnabled(True)

        layout = QVBoxLayout(self)
        layout.addWidget(self.table_view)
        self.setLayout(layout)



    def update_model(self):
        self.table_model = MyTableModel(self, self.dataList, self.header)
        self.table_view.setModel(self.table_model)
        self.table_view.update()

    def findLabelName(self,rowindex):
        return self.dataList[rowindex][-1]

    def doubleclickedaction(self,index):
        self.doubleClicked.emit(index.row())
        self.currentrow = index.row()
        print ('doubleclicked',self.findLabelName(index.row()))


    def checkboxchecked(self,value):
        print ('table checkboxchecked',self.currentrow,value)
        # self.currentrow = index.row()
        if value == True:
            self.Checkboxcheckvalue.emit(True)
        else:
            self.Checkboxcheckvalue.emit(False)


    def selectedLabel(self,index):
        return self.findLabelName(index.row())



    def showSelection(self, item):
        cellContent = item.data()
        # print(cellContent)  # test
        sf = "You clicked on {}".format(cellContent)
        # display in title bar for convenience
        self.setWindowTitle(sf)

    def selectRow(self, index):
        self.Rowselected.emit(index.row())
        self.currentrow = index.row()
        print("current row is %d", index.row())
        pass


class MyTableModel(QAbstractTableModel):
    """
    keep the method names
    they are an integral part of the model
    """

    CheckBoxValue = pyqtSignal(bool)
    def __init__(self, parent, mylist, header, *args):
        QAbstractTableModel.__init__(self, parent, *args)
        self.mylist = mylist
        self.header = header

    def setDataList(self, mylist):
        self.mylist = mylist
        self.layoutAboutToBeChanged.emit()
        self.dataChanged.emit(self.createIndex(0, 0), self.createIndex(self.rowCount(0), self.columnCount(0)))
        self.layoutChanged.emit()

    def rowCount(self, parent):
        if self.mylist != []:
            return len(self.mylist)
        else:
            return 0

    def columnCount(self, parent):
        if self.mylist != []:
            return len(self.mylist[0])-1
        else:
            return 0

    def data(self, index, role):
        if not index.isValid():
            return None
        if (index.column() == 0):
            value = self.mylist[index.row()][index.column()].text()
        else:
            value = self.mylist[index.row()][index.column()]
        if role == QtCore.Qt.EditRole:
            return value
        elif role == QtCore.Qt.DisplayRole:
            return value
        elif role == QtCore.Qt.CheckStateRole:
            if index.column() == 0:
                if self.mylist[index.row()][index.column()].isChecked():
                    return QtCore.Qt.Checked
                else:
                    return QtCore.Qt.Unchecked

    def headerData(self, col, orientation, role):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            return self.header[col]
        return None

    def sort(self, col, order):
        """sort table by given column number col"""
        if col != 0:
            pass
        else:
            col = -1
        self.emit(SIGNAL("layoutAboutToBeChanged()"))
        self.mylist = sorted(self.mylist, key=operator.itemgetter(col))
        if order == Qt.DescendingOrder:
            self.mylist.reverse()
        self.emit(SIGNAL("layoutChanged()"))
        print 'sorted'

    def flags(self, index):
        if not index.isValid():
            return None
        if index.column() == 0:
            return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable
        else:
            return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable

    def setData(self, index, value, role):
        if not index.isValid():
            return False
        if role == QtCore.Qt.CheckStateRole and index.column() == 0:
            if value == QtCore.Qt.Checked:
                self.mylist[index.row()][index.column()].setChecked(True)
                print('checked',index.row())
                self.CheckBoxValue.emit(True)

            else:
                self.mylist[index.row()][index.column()].setChecked(False)
                print('unchecked',index.row())
                self.CheckBoxValue.emit(False)
        self.dataChanged.emit(index, index)
        return True

if __name__ == '__main__':
    app = QApplication([])
    header = ['name', 'type', 'segment', 'exit', 'entry']
    dataList = [
        [QtGui.QCheckBox('line9'), 'line', '058176', '01', '1705','line9'],
        [QtGui.QCheckBox('line3'), 'line', '058176', '02', '1705','line3'],
        [QtGui.QCheckBox('line6'), 'line', '058176', '03', '1705','line6'],
        [QtGui.QCheckBox('line1'), 'line', '058176', '04', '1705','line'],
        [QtGui.QCheckBox('line4'), 'line', '058176', '01', '1705','line4'],
        [QtGui.QCheckBox('area4'), 'area', '058176', '02', '1705','area4'],
        [QtGui.QCheckBox('area2'), 'area', '058176', '02', '1705','area2'],
        [QtGui.QCheckBox('area8'), 'area', '058176', '01', '1705','area8'],
    ]

    win = MyTable()
    win.dataList = dataList
    win.header = header
    win.update_model()
    win.show()
    app.exec_()

在您的情况下,您已在MyTable构造函数中创建了table_model,并与该对象建立了连接,但是稍后在update_model方法中创建了新模型,因此先前的模型及其连接也已删除。

def update_model(self):
    self.table_model = MyTableModel(self, self.dataList, self.header)
    self.table_view.setModel(self.table_model)
    self.table_model.CheckBoxValue.connect(self.checkboxchecked)
    self.table_view.update()

尽管我更喜欢更新模型,而不是为其创建新模型,但我将创建一种方法来更新数据:

class MyTableModel(QAbstractTableModel):
    """
    keep the method names
    they are an integral part of the model
    """

    CheckBoxValue = pyqtSignal(bool)
    def __init__(self, parent, mylist, header, *args):
        QAbstractTableModel.__init__(self, parent, *args)
        self.mylist = mylist
        self.header = header

    def update_model(self,  mylist, header):
        self.beginResetModel()
        self.mylist = mylist
        self.header = header
        self.endResetModel()

    [...]

并在表的update_model中:

class MyTable(QWidget):
    [...]
    def update_model(self):
        self.table_model.update_model(self.dataList, self.header)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM