Qt TableView index带/不带标头

时间:2018-02-01 14:24:48

标签: python pyside qtableview

使用PySide 1.2

抓取QTableView中单击项目的索引会返回不同的结果,不管是否存在水平标题。 如果存在水平标题,则它似乎包含在visualRect的计算中。所以第一行,第一列索引不再是0,0而是1,0。

这是打算吗?因为它真的令人困惑和不方便,因为最后一行索引无效。

重现:

import re
import operator
import os
import sys 
# from Qt.QtCore import * 
# from Qt.QtGui import * 
# from Qt.QtWidgets import * 
from PySide.QtCore import * 
from PySide.QtGui import * 


def main(): 
    app = QApplication(sys.argv) 
    w = MyWindow() 
    w.show() 
    sys.exit(app.exec_()) 


class CustomTableView(QTableView):
    """
    """

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

    def mousePressEvent(self, mouse_event):
        """
        """
        view_pos = self.mapFromGlobal(mouse_event.globalPos())
        index = self.indexAt(view_pos)
        print('mouse press index not  cutting header : ' + str((index.row(), index.column())))
        view_pos.setY(view_pos.y() - self.horizontalHeader().sizeHint().height())
        index = self.indexAt(view_pos)
        print('mouse press index cutting header : ' + str((index.row(), index.column())))
        super(CustomTableView, self).mousePressEvent(mouse_event)


class MyWindow(QWidget): 
    def __init__(self, *args): 
        QWidget.__init__(self, *args) 

        # create table
        self.get_table_data()
        table = self.createTable() 

        # layout
        layout = QVBoxLayout()
        layout.addWidget(table) 
        self.setLayout(layout) 

    def get_table_data(self):
        stdouterr = os.popen4("dir c:\\")[1].read()
        lines = stdouterr.splitlines()
        lines = lines[5:]
        lines = lines[:-2]
        self.tabledata = [re.split(r"\s+", line, 4)
                     for line in lines]

    def createTable(self):
        # create the view
        tv = CustomTableView()

        # set the table model
        header = ['date', 'time', '', 'size', 'filename']
        tm = MyTableModel(self.tabledata, header, self) 
        tv.setModel(tm)
        return tv

class MyTableModel(QAbstractTableModel): 
    def __init__(self, datain, headerdata, parent=None, *args): 
        """ datain: a list of lists
            headerdata: a list of strings
        """
        QAbstractTableModel.__init__(self, parent, *args) 
        self.arraydata = datain
        self.headerdata = headerdata

    def rowCount(self, parent): 
        return len(self.arraydata)

    def columnCount(self, parent): 
        return len(self.arraydata[0]) 

    def data(self, index, role): 
        if not index.isValid(): 
            return None 
        elif role != Qt.DisplayRole: 
            return None 
        return self.arraydata[index.row()][index.column()]

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

if __name__ == "__main__": 
    main()

1 个答案:

答案 0 :(得分:2)

您不必使用全局位置然后将其传递到本地位置,因为您将获得相对于QTableView上角的位置,但indexAt根据{需要相对于内容的位置{3}}:

  

PySide.QtGui.QAbstractItemView.indexAt(point)

     

参数:point - PySide.QtCore.QPoint

     

返回类型:PySide.QtCore.QModelIndex

     

返回viewport coordinates point处项目的模型索引。

您必须使用活动的位置:mouse_event.pos()

def mousePressEvent(self, mouse_event):
    index = self.indexAt(mouse_event.pos())
    print('mouse press index: ' + str((index.row(), index.column())))
    super(CustomTableView, self).mousePressEvent(mouse_event)

如果您想使用全球排名,则必须将其转换为与viewport()相关的本地排名:

def mousePressEvent(self, mouse_event):
    view_pos = self.viewport().mapFromGlobal(mouse_event.globalPos())
    index = self.indexAt(view_pos)
    print('mouse press index : ' + str((index.row(), index.column())))
    super(CustomTableView, self).mousePressEvent(mouse_event)