简体   繁体   中英

Set pyqt qtablewidget horizontal header lable editable

How can I edit the label of a horizontal header in a qtablewidget by double clicking on it? What I have so far but does not work. So when someone doubleclicks the top header, a linedit pops up allows for text and then resets the label.

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()

To be honest, I couldn't figure out what you're trying to do with that QLineEdit . But as far as I can see, you are halfway there. Using sectionDoubleClicked signal of the horizontalHeader() is a good start. But the rest is a big question mark for me.

All you need to do is this: Get the header item with horizontalHeaderItem(index) and use text to get the value or setText to set the new value.

And you might consider QInputDialog.getText to obtain the new value from the user.

Here is a minimal example that shows this:

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_())

I found this answer from mechsin on QtCentre and it worked for me:

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

See last comment in the thread. In summary, it creates a QLineEdit in the viewport of the table header. A slot for double-clicking the header shows the line edit in the proper position and width to cover the header section. A slot for finishing the line edit hides the line edit and captures its text value for the header item.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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