单击时发出 QTableWidgetItem 特定信号

Emiting QTableWidgetItem specific signal on being clicked

我想实现 QTableWidget 中的多个 QTableWidgetItems 可以 selected 和 unselected 的功能,以便这些 QTableWidgetItems 的值和 "positions" 是已知的进一步使用。

QTableWidget 内部有一些空单元格,aesthetics/spacing,我试图实现的功能应该忽略这些单元格。 但这也可以在事后通过检查 selected 项目是否包含内容来轻松完成。

self.table_widget.itemClicked.connect(self.some_function)

将是最合适的信号,但我无法指定或知道在 table 小部件内单击了哪个项目,或者是 selected 还是未selected。

问题:如何实现在按下特定 QTableWidgetItem 时发出特定信号的功能?


这里有一些用于示例的伪代码:

class Window(QtWidgets.QMainWindow):
    def __init__(self):

        super(Window, self).__init__()
        uic.loadUi("qtdesignerfile.ui", self)
        self.show()
        #connect signal to function
        self.table_widget.itemClicked.connect(self.some_function)
        #create "global" list to save all selected items
        self.selected_items = []

    #some function to execute the logic
    def some_function(self):
        #condition distinguishing if item was just selected or unselected
        if QTableWidgetItem(row, column) is not already selected:

            #change background color to indicate selection
            self.table_widget.item(row,column).setBackground(QtGui.QColor(100,100,100))
            #"format" information of clicked item for further use
            selected_item = [str(table_widget.item(row,column).text()), row, column]
            #"save" selected item in global list for further use
            self.selected_items.append(selected_item)

        #condition distinguishing if item was just selected or unselected
        if QTableWidgetItem(row, column) is already selected:

            #change background color to indicate un-selection 
            self.table_widget.item(row,column).setBackground(QtGui.QColor(0,0,0))
            #"format" information of clicked item for further use
            selected_item = [str(table_widget.item(row,column).text()), row, column]
            #remove the un-selected item from global list
            self.selected_items.remove(selected_item)


示例ui-文件:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>418</width>
    <height>297</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QGridLayout" name="gridLayout">
    <item row="0" column="0">
     <widget class="QTableWidget" name="table_widget">
      <row>
       <property name="text">
        <string>Row 1</string>
       </property>
      </row>
      <row>
       <property name="text">
        <string>Row 2</string>
       </property>
      </row>
      <row>
       <property name="text">
        <string>Row 3</string>
       </property>
      </row>
      <row>
       <property name="text">
        <string>Row 4</string>
       </property>
      </row>
      <row>
       <property name="text">
        <string>Row 5</string>
       </property>
      </row>
      <row>
       <property name="text">
        <string>Row 6</string>
       </property>
      </row>
      <column>
       <property name="text">
        <string>Grouping</string>
       </property>
      </column>
      <column>
       <property name="text">
        <string>Column 2</string>
       </property>
      </column>
      <column>
       <property name="text">
        <string>Column 3</string>
       </property>
      </column>
      <item row="0" column="0">
       <property name="text">
        <string>category 1</string>
       </property>
      </item>
      <item row="1" column="1">
       <property name="text">
        <string>Entry (1,1)</string>
       </property>
      </item>
      <item row="1" column="2">
       <property name="text">
        <string>Entry(1,2)</string>
       </property>
      </item>
      <item row="2" column="1">
       <property name="text">
        <string>Entry(2,1)</string>
       </property>
      </item>
      <item row="2" column="2">
       <property name="text">
        <string>Entry(2,2)</string>
       </property>
      </item>
      <item row="3" column="0">
       <property name="text">
        <string>category 2</string>
       </property>
      </item>
      <item row="4" column="1">
       <property name="text">
        <string>Entry(4,1)</string>
       </property>
      </item>
      <item row="4" column="2">
       <property name="text">
        <string>Entry(4,2)</string>
       </property>
      </item>
      <item row="5" column="1">
       <property name="text">
        <string>Entry(5,1)</string>
       </property>
      </item>
      <item row="5" column="2">
       <property name="text">
        <string>Entry(5,2)</string>
       </property>
      </item>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>418</width>
     <height>21</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>


我对如何轻松实现此功能感到非常困惑,并且愿意接受有关不同方法的建议。

应用程序的用户应该能够select多个QTableWidgetItems,以便可以将项目所在行的信息转移到另一个QTableWidget以供进一步使用。

如果元素存在,itemClicked 信号确实传递被按下的元素,默认情况下 Qt Designer 只创建它编辑过的元素,在适当的地方放置文本。

from PyQt5 import QtCore, QtGui, QtWidgets, uic

SelectedRole = QtCore.Qt.UserRole + 1000


class Window(QtWidgets.QMainWindow):
    def __init__(self):

        super(Window, self).__init__()
        uic.loadUi("qtdesignerfile.ui", self)

        # self.tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        self.tableWidget.itemClicked.connect(self.onClicked)

    @QtCore.pyqtSlot(QtWidgets.QTableWidgetItem)
    def onClicked(self, it):
        state = not it.data(SelectedRole)
        it.setData(SelectedRole, state)
        it.setBackground(
            QtGui.QColor(100, 100, 100) if state else QtGui.QColor(0, 0, 0)
        )


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Window()
    w.show()
    sys.exit(app.exec_())