使 pyqt 的 QTableWidget 水平标题可编辑

5

如何通过双击水平标题来编辑qtablewidget中的标签? 以下是我目前的代码,但无法正常工作。因此,当有人双击顶部标题时,会弹出一个linedit允许输入文本,然后重置标签。

import sys
from PyQt4 import QtGui,QtCore
import generate_file


class WebGetMain(QtGui.QMainWindow,generate_file):
    def __init__(self,parent=None):
        super(WebGetMain,self).__init__(parent)
        self.setupUi(self)
        #set these values customizable before user populates the table
        self.row_count = 20
        self.col_count = 20
        #setup actual cols,rows
        self.web_get_table.setRowCount(self.row_count)
        self.web_get_table.setColumnCount(self.col_count)
        #allow horizontal header to be altered
        #create and initialize linedit
        self.linedit = QtGui.QLineEdit(parent=self.web_get_table.viewport())
        self.linedit.setAlignment(QtCore.Qt.AlignTop)
        self.linedit.setHidden(True)
        self.linedit.editingFinished.connect(self.doneEditing)
        #connect double click action on header
        self.web_get_table.connect(self.web_get_table.horizontalHeader(),QtCore.SIGNAL('sectionDoubleClicked(int)'),self.on_header_doubleClicked)
        #setup vertical scrollbars for adding rows
        self.vBar = self.web_get_table.verticalScrollBar()
        self._vBar_lastVal = self.vBar.value()

        #initialize cols,rows
        for column in range(0, 2):
            for row in range(0, 3):
                print row, column
                item = QtGui.QTableWidgetItem()
                self.web_get_table.setItem(row, column, item)
        #scrollbar value signal to detect for scrolling
        self.vBar.valueChanged.connect(self.scrollbarChanged)

    def scrollbarChanged(self, val):
        #initialize scrollbar
        bar = self.vBar
        minVal, maxVal = bar.minimum(), bar.maximum()
        avg = (minVal+maxVal)/2
        rowCount = self.web_get_table.rowCount()

        # scrolling down
        if val > self._vBar_lastVal and val >= avg:
            self.web_get_table.insertRow(rowCount)

        # scrolling up
        elif val < self._vBar_lastVal:
            lastRow = rowCount-20
            empty = True
            for col in xrange(self.web_get_table.columnCount()):
                item = self.web_get_table.item(lastRow, col)
                if item and item.text():
                    empty=False
                    break
            if empty:
                #remove rows when scrolling up
                self.web_get_table.removeRow(lastRow)
        self._vBar_lastVal = val

    def doneEditing(self):
        self.linedit.blockSignals(True)
        self.linedit.setHidden(True)
        oldname = self.web_get_table.model().dataset.field(self.sectionedit)
        newname = str(self.linedit.text())
        self.web_get_table.model().dataset.changeFieldName(oldname,newname)
        self.linedit.setText('')
        self.web_get_table.setCurrentIndex(QtCore.QModelIndex())        

    def on_header_doubleClicked(self,item):
        self.linedit.setText(self.web_get_table.model().field(item).name)
        self.linedit.setHidden(False)
        self.linedit.blockSignals(False)
        self.linedit.setFocus()
        self.linedit.selectAll()
        self.sectionedit = item

def main():
    app = QtGui.QApplication(sys.argv)
    app.setStyle(QtGui.QStyleFactory.create("Plastique"))
    main_window = WebGetMain()
    main_window.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()
2个回答

11
说实话,我无法理解你打算如何使用那个 QLineEdit。但就我所看到的,你已经有了一半的进展。使用 horizontalHeader()sectionDoubleClicked 信号是一个不错的开始。但其余部分对我来说是一个大问号。
你所需要做的就是:用 horizontalHeaderItem(index) 获取标题项,然后使用 text 获取值或者使用 setText 设置新值。
你可以考虑使用 QInputDialog.getText 来从用户那里获取新值。
这是一个最简单的示例,演示了如何实现:
import sys
from PyQt4 import QtGui

class MyWindow(QtGui.QWidget):
    def __init__(self, parent=None):
        super(MyWindow, self).__init__(parent)

        self.table = QtGui.QTableWidget(5,5)
        self.table.setHorizontalHeaderLabels(['1', '2', '3', '4', '5'])
        self.table.setVerticalHeaderLabels(['1', '2', '3', '4', '5'])
        self.table.horizontalHeader().sectionDoubleClicked.connect(self.changeHorizontalHeader)

        layout = QtGui.QHBoxLayout()
        layout.addWidget(self.table)
        self.setLayout(layout)

    def changeHorizontalHeader(self, index):
        oldHeader = self.table.horizontalHeaderItem(index).text()
        newHeader, ok = QtGui.QInputDialog.getText(self,
                                                      'Change header label for column %d' % index,
                                                      'Header:',
                                                       QtGui.QLineEdit.Normal,
                                                       oldHeader)
        if ok:
            self.table.horizontalHeaderItem(index).setText(newHeader)


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)

    main = MyWindow()
    main.show()

    sys.exit(app.exec_())

1

我在QtCentre上找到了这个来自mechsin的答案,它对我有用:

http://www.qtcentre.org/threads/12835-How-to-edit-Horizontal-Header-Item-in-QTableWidget

请查看线程中的最后一条评论。简而言之,它在表头的视口中创建了一个QLineEdit。双击表头的插槽会在适当的位置和宽度上显示行编辑器,以覆盖表头部分。完成行编辑的插槽会隐藏行编辑并捕获其文本值以用于表头项。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接