2

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

  • 3
    Please provide a [minimal, reproducible example](https://stackoverflow.com/help/minimal-reproducible-example). – musicamante Apr 24 '20 at 05:48
  • Thanks for your interest. I uploaded a photo. I even select these texts to copy to the windows clipboard. For example, I want to select text 'Tesis' and copy with ctrl+c to paste it Chrome. It is so simple but I can't select the text. – Samet Yıldırım Apr 24 '20 at 06:10

1 Answers1

5

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)
musicamante
  • 41,230
  • 6
  • 33
  • 58
  • class final(QMainWindow,gui.Ui_MainWindow): def __init__(self): super(final,self).__init__() self.setupUi(self) self.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse) If I run this code, I get the error: "'final' object has no attribute 'setTextInteractionFlags'". Also I tried to do it only on qtablewidget and got the same error. Only it works for Qmessagebox. – Samet Yıldırım Apr 24 '20 at 23:44
  • Please edit your question and provide a minimal reproducible example as already requested. – musicamante Apr 25 '20 at 02:58
  • I added a sample code. How can I select the word trial on qtablewidget and text (Gündüz)? – Samet Yıldırım Apr 25 '20 at 22:27
  • I updated the answer. For future reference, be more clear in your questions. In the image you originally posted you showed that you wanted to select the text from a the label, not from the table. Those are two completely different things. – musicamante Apr 26 '20 at 03:55
  • Hello my friend again. I was planning to answer you after finishing the project in case of facing new problems to ask you. Im sorrry for delay and thank you for your effort. I tried both of your suggestions but it didn't work. I uploaded my gui and both implemented method you suggested to select and copy qtablewidget to Github in the following url: https://github.com/sametyildirima/Selectable-QtableWidget .Im dealing with numbers and copying them is so important. – Samet Yıldırım May 12 '20 at 15:40
  • @sametyıldırım you disabled the table. If a widget is disabled no keyboard/mouse interaction is allowed. – musicamante May 12 '20 at 16:38
  • Now I understand, Im grateful for your help – Samet Yıldırım May 14 '20 at 21:42