Как отметить QRadioButton по клику на строку?

Рейтинг: 1Ответов: 1Опубликовано: 31.01.2023

В моей таблице имеется столбец, где в ячейках находится widget с QRadioButton. Я хочу сделать так, чтобы при выборе строки по клику на эту кнопку или на саму строку выделялась вся строка и кнопка переходила в состояние Toggled\Checked (в будущем я данные этой строки буду отправлять в БД). Соответственно, при клике по двум разным строкам, выбраться должна последняя.

Я реализовал данный алгоритм, но несколько грубо: по новой создаю и вставляю виджеты, которые по умолчанию Unchecked. И это кажется мне довольно нерациональным... Я пробовал отхватывать item(), переписывал эти кнопки просто на layout с grid и пробовал вставлять просто item-ы и их изменять - всё тщетно.

Как реализовать клик по строке и выбор QRadioButton с выделением строки (и наоборот), а также, возможно ли просто менять состояние в них, а не как я - пересоздавать?

кстати, можно ли при наведении мыши выделять всю строку, а не ячейку? QAbstractItemView.setSelectionBehavior(QAbstractItemView.SelectRows) помог только с выбором

Нажал на кнопку - всё сработало

При нажатии просто на строку должен переключиться qradiobutton

main.py

import sys

from PyQt5 import QtWidgets, QtCore, QtGui
from ui import untitled


class MainWindow(QtWidgets.QMainWindow, untitled.Ui_Form):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.ui = untitled.Ui_Form()
        self.setupUi(self)

        self.insert_rb(self.tableWidget)

    def create_radioButton(self):  # Метод создания рб на виджете
        widget = QtWidgets.QWidget()
        rb = QtWidgets.QRadioButton()
        pLayout = QtWidgets.QHBoxLayout(widget)
        pLayout.addWidget(rb)
        pLayout.setAlignment(QtCore.Qt.AlignCenter)
        pLayout.setContentsMargins(0, 0, 0, 0)
        widget.setLayout(pLayout)
        return widget, rb

    def insert_rb(self, table):  # Метод вставки в таблицу рб-шек
        row_count = table.rowCount()
        for i in range(row_count):
            widget, radio = self.create_radioButton()
            radio.toggled.connect(lambda: self.currentPos(table, row_count))
            table.setCellWidget(i, 0, widget)

    def currentPos(self, table, row_count):  # здесь весь функционал РБ при клике
        rbClick = QtWidgets.qApp.focusWidget()
        index = table.indexAt(rbClick.parent().pos())
        columns = table.columnCount()
        if index.isValid():
            print(index.row(), index.column())
            table.selectRow(index.row())
            print(table.item(index.row(), 2).text())
            for i in range(row_count):
                if i != index.row():
                    widget, radio = self.create_radioButton()
                    radio.toggled.connect(lambda: self.currentPos(table, row_count))
                    table.setCellWidget(i, 0, widget)
                    # item = table.item(i, 0) (следы неудачных попыток оптимизирования)
                    # item.setCheckState(False) (следы неудачных попыток оптимизирования)


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

untitled.py (конвертировал из .ui в .py)

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(702, 320)
        self.tableWidget = QtWidgets.QTableWidget(Form)
        self.tableWidget.setGeometry(QtCore.QRect(220, 60, 321, 151))
        self.tableWidget.setStyleSheet("QTableWidget::item:hover {\n"
"    color: white;\n"
"    background-color: red;\n"
"}      \n"
"\n"
"QTableWidget::item:selected\n"
"{\n"
"     color: white;\n"
"    background-color: green;\n"
"    \n"
"}\n"
"")
        self.tableWidget.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
        self.tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        self.tableWidget.setShowGrid(True)
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(3)
        self.tableWidget.setRowCount(2)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(0, 0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(0, 1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(0, 2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(1, 0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(1, 1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(1, 2, item)

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

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.tableWidget.setSortingEnabled(True)
        item = self.tableWidget.verticalHeaderItem(0)
        item.setText(_translate("Form", "1"))
        item = self.tableWidget.verticalHeaderItem(1)
        item.setText(_translate("Form", "2"))
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText(_translate("Form", "New Column"))
        item = self.tableWidget.horizontalHeaderItem(1)
        item.setText(_translate("Form", "1"))
        item = self.tableWidget.horizontalHeaderItem(2)
        item.setText(_translate("Form", "3"))
        __sortingEnabled = self.tableWidget.isSortingEnabled()
        self.tableWidget.setSortingEnabled(False)
        item = self.tableWidget.item(0, 1)
        item.setText(_translate("Form", "sssss"))
        item = self.tableWidget.item(0, 2)
        item.setText(_translate("Form", "xxxxxxx"))
        item = self.tableWidget.item(1, 1)
        item.setText(_translate("Form", "ttttt"))
        item = self.tableWidget.item(1, 2)
        item.setText(_translate("Form", "jjjjjj"))
        self.tableWidget.setSortingEnabled(__sortingEnabled)


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    Form = QtWidgets.QWidget()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())

Ответы

▲ 1Принят

Попробуйте так:

import sys
from PyQt5 import QtWidgets, QtCore, QtGui

#from ui import untitled
class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(702, 320)
        self.tableWidget = QtWidgets.QTableWidget(Form)
        self.tableWidget.setGeometry(QtCore.QRect(220, 60, 321, 151))
        self.tableWidget.setStyleSheet("QTableWidget::item:hover {\n"
"    color: white;\n"
"    background-color: red;\n"
"}      \n"
"\n"
"QTableWidget::item:selected\n"
"{\n"
"     color: white;\n"
"    background-color: green;\n"
"    \n"
"}\n"
"")
        self.tableWidget.setSelectionMode(
            QtWidgets.QAbstractItemView.SingleSelection)
        self.tableWidget.setSelectionBehavior(
            QtWidgets.QAbstractItemView.SelectRows)
        self.tableWidget.setShowGrid(True)
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(3)
        self.tableWidget.setRowCount(3)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(0, 0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(0, 1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(0, 2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(1, 0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(1, 1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(1, 2, item)

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

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))
        self.tableWidget.setSortingEnabled(True)
        item = self.tableWidget.verticalHeaderItem(0)
        item.setText(_translate("Form", "1"))
        item = self.tableWidget.verticalHeaderItem(1)
        item.setText(_translate("Form", "2"))
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText(_translate("Form", "New Column"))
        item = self.tableWidget.horizontalHeaderItem(1)
        item.setText(_translate("Form", "1"))
        item = self.tableWidget.horizontalHeaderItem(2)
        item.setText(_translate("Form", "3"))
        __sortingEnabled = self.tableWidget.isSortingEnabled()
        self.tableWidget.setSortingEnabled(False)
        item = self.tableWidget.item(0, 1)
        item.setText(_translate("Form", "sssss"))
        item = self.tableWidget.item(0, 2)
        item.setText(_translate("Form", "xxxxxxx"))
        item = self.tableWidget.item(1, 1)
        item.setText(_translate("Form", "ttttt"))
        item = self.tableWidget.item(1, 2)
        item.setText(_translate("Form", "jjjjjj"))
        
        item = QtWidgets.QTableWidgetItem("Hello")                 # +
        self.tableWidget.setItem(2, 1, item)                       # +
        item = QtWidgets.QTableWidgetItem("World")                 # +
        self.tableWidget.setItem(2, 2, item)                       # +
        
        self.tableWidget.setSortingEnabled(__sortingEnabled)


class MainWindow(QtWidgets.QMainWindow, Ui_Form):
    def __init__(self):
        super(MainWindow, self).__init__()
        
# ?        self.ui = untitled.Ui_Form()
        self.setupUi(self)

        self.tableWidget.cellClicked.connect(self.cell_row)              # +++
        self.row_selected = None                                         # +++
        self.insert_rb()

# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
    def cell_row(self, row, column):
        #print(f'\nrow={row}; column={column}')  
        self.row_selected = row
        rb = self.button_group.button(row)
        rb.click()
    
    def insert_rb(self):        # Метод вставки в таблицу рб-шек
        row_count = self.tableWidget.rowCount()
        
        self.button_group = QtWidgets.QButtonGroup(self)                 # <--- 
        self.button_group.setExclusive(True)                             # <---
        
        for i in range(row_count):
            widget, radio = self.create_radioButton()
            radio.toggled.connect(lambda ch, row=i: self.currentPos(ch, row))
            self.tableWidget.setCellWidget(i, 0, widget)   
            
            self.button_group.addButton(radio)                           # <---
            self.button_group.setId(radio, i)                            # <---

    def currentPos(self, ch, row): 
        #print(f'row = {row} -- {ch}')  
        if ch:
            self.row_selected = row
            self.tableWidget.selectRow(row)
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

    def create_radioButton(self):  # Метод создания рб на виджете
        widget = QtWidgets.QWidget()
        rb = QtWidgets.QRadioButton()
        pLayout = QtWidgets.QHBoxLayout(widget)
        pLayout.addWidget(rb)
        pLayout.setAlignment(QtCore.Qt.AlignCenter)
        pLayout.setContentsMargins(0, 0, 0, 0)
        widget.setLayout(pLayout)
        return widget, rb


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

введите сюда описание изображения

введите сюда описание изображения

введите сюда описание изображения