Samet Yıldırım
Samet Yıldırım

Reputation: 49

Select a text in PYQT to copy

I designed a windows desktop app with QT Designer and PYQT5. The problem is that, I can not select any item, text on main window, or on qtablewidget to paste it manually somewhere else. It will make things easier for users not for me.

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
        self.tableWidget.setGeometry(QtCore.QRect(260, 160, 256, 192))
        self.tableWidget.setRowCount(3)
        self.tableWidget.setColumnCount(2)
        self.tableWidget.setObjectName("tableWidget")
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(1, 0, item)
        self.input_gunduz = QtWidgets.QLineEdit(self.centralwidget)
        self.input_gunduz.setGeometry(QtCore.QRect(370, 70, 71, 20))
        self.input_gunduz.setObjectName("input_gunduz")
        self.label_5 = QtWidgets.QLabel(self.centralwidget)
        self.label_5.setGeometry(QtCore.QRect(220, 70, 101, 21))
        font = QtGui.QFont()
        font.setPointSize(9)
        font.setBold(True)
        font.setWeight(75)
        self.label_5.setFont(font)
        self.label_5.setObjectName("label_5")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        __sortingEnabled = self.tableWidget.isSortingEnabled()
        self.tableWidget.setSortingEnabled(False)
        item = self.tableWidget.item(1, 0)
        item.setText(_translate("MainWindow", "trial"))
        self.tableWidget.setSortingEnabled(__sortingEnabled)
        self.label_5.setText(_translate("MainWindow", "Gündüz (kWhr):"))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

The code is as seen above. Please help me make the main window selectable

Upvotes: 2

Views: 5966

Answers (2)

Jcyrss
Jcyrss

Reputation: 1798

In case anyone need sample code of PySide6

from PySide6 import QtGui

# other code here

label = QLabel(self.window)
label.setTextInteractionFlags(
  QtGui.Qt.TextSelectableByMouse|QtGui.Qt.TextSelectableByKeyboard
)

Upvotes: 0

musicamante
musicamante

Reputation: 48260

Copying of text does not work in the same way for every widget, because each widget type uses even radically different way to show or interact with text.

If you want to copy the text of a QLabel, you have to make it selectable (by using label.setTextInteractionFlags(Qt.TextSelectableByMouse)).

But if you want to copy the text from QTableWidget, things are very different, since a table allows interaction with their items that prevent a simple text selection.

Obviously, the most simple method would be to start editing the item (assuming it's editable) and select its text, but if you want other ways to do that, it depends on how you want to be able to copy the text.

A possibility is to use the ctrl+c keyboard shortcut. To do so, we need to install an event filter on the table widget:

from PyQt5 import QtCore, QtGui, QtWidgets
from mainwindow import Ui_MainWindow

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

        # install an event filter on the table widget, so that we can filter all
        # its event, including keyboard presses
        self.tableWidget.installEventFilter(self)

    def eventFilter(self, source, event):
        if event.type() == QtCore.QEvent.KeyPress and event == QtGui.QKeySequence.Copy:
            # check if an index is currently selected and it has text
            text = self.tableWidget.currentIndex().data()
            if text:
                # copy that text to the clipboard
                QtWidgets.QApplication.clipboard().setText(text)
        return super().eventFilter(source, event)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

Note that in the example above I used the multiple inheritance method explained in the documentation about using Designer with ui files. You should never edit the files created by pyuic.

It's also possible to set a menu for the table widget and copy the text from there:

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        # ...

        # use the custom context menu policy for the table widget, so that we can
        # connect the menu request to a slot
        self.tableWidget.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.tableWidget.customContextMenuRequested.connect(self.showTableMenu)

    def showTableMenu(self, pos):
        # get the text of the index at the mouse cursor (if any)
        text = self.tableWidget.indexAt(pos).data()
        menu = QtWidgets.QMenu()
        copyAction = menu.addAction('Copy')
        if not text:
            copyAction.setEnabled(False)
        # show the menu
        res = menu.exec_(QtGui.QCursor.pos())
        if res == copyAction:
            # if the menu has been triggered by the action, copy to the clipboard
            QtWidgets.QApplication.clipboard().setText(text)

Upvotes: 7

Related Questions