I have a QTableWidget that when a row is clicked, it selects all cells in that row. I am trying to add a "copy" functionality so that I can ^ctrl-c when row(s) are selected and paste into a text editor. However, with my current code, once i ^ctrl-c a row, the line that I copied keeps getting copied.
I have implemented a print statement in my method "read_clipboard" to see whether or not the line copied was read, and this is how I found out that the line keeps getting copied as if in an infinite loop.
None of the previous stack overflow questions on PyQt/Qt and QClipboard have been effective for me.
def __init__(self):
super(MainWindow, self).__init__()
self.setupUi(self)
self.my_selector = self.my_tableWidget.selectionModel()
# Where I detect the signal to call my "read_clipboard" method
QtGui.QGuiApplication.clipboard().dataChanged.connect(self.read_clipboard)
self.show()
def read_clipboard(self):
selection = self.my_selector.selectedIndexes()
if selection:
print(selection)
QtGui.QGuiApplication.clipboard().clear()
QtGui.QGuiApplication.clipboard().setText(selection)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
mainWin = MainWindow() # Creates MainWindow object
ret = app.exec_()
sys.exit(ret)
When I ^ctrl-c a row, the program prints the "selection" continuously as if it is in an infinite loop, I don't know how to stop it after it runs just once so that I can just copy that one line.
You shouldn't use the
dataChanged
signal in this way for two reasons:read_clipboard
method; you could obviously temporarily disconnect the signal as suggested by @furas, but the first problem will remain.Also, you can't use a QItemSelectionModel for
setText
, as it expects a string.A better solution is to override the keyPressEvent of a custom QTableWidget class, to catch it's "copy" action before the default implementation acts upon it:
Another similar possibility is to install an event filter to your table and check for its key events: