Как отметить QRadioButton по клику на строку?
В моей таблице имеется столбец, где в ячейках находится widget с QRadioButton. Я хочу сделать так, чтобы при выборе строки по клику на эту кнопку или на саму строку выделялась вся строка и кнопка переходила в состояние Toggled\Checked (в будущем я данные этой строки буду отправлять в БД). Соответственно, при клике по двум разным строкам, выбраться должна последняя.
Я реализовал данный алгоритм, но несколько грубо: по новой создаю и вставляю виджеты, которые по умолчанию Unchecked. И это кажется мне довольно нерациональным... Я пробовал отхватывать item(), переписывал эти кнопки просто на layout с grid и пробовал вставлять просто item-ы и их изменять - всё тщетно.
Как реализовать клик по строке и выбор QRadioButton с выделением строки (и наоборот), а также, возможно ли просто менять состояние в них, а не как я - пересоздавать?
кстати, можно ли при наведении мыши выделять всю строку, а не ячейку? QAbstractItemView.setSelectionBehavior(QAbstractItemView.SelectRows) помог только с выбором
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_())




