2015-04-14 6 views
1

[Я использую PyQt4, но я думаю, что этот вопрос Qt4 не Python специфичны.]Получить индекс строки QTableWidget зная его элементы

У меня есть QTableWidget. В каждой строке первый столбец содержит кнопку. При щелчке строка удаляется.

Чтобы удалить строку, я использую метод removeRow(int row), который принимает в качестве аргумента индекс строки. При подключении сигнала я не могу знать индекс строки, потому что он может меняться тем временем (например, если первая строка удалена, все индексы строк меняются).

The accepted answer here предлагает передать обратный вызов экземпляр QTableWidgetItem в строке, а затем получить номер строки из этого элемента во время удаления.

Это было бы хорошо, если только ни один из элементов строки не является QTableWidgetItem. Элементами являются сама кнопка и несколько ComboBoxes.

Я не могу найти способ обойти это.

Могу ли я каким-то образом подогнать один из моих элементов в QTableWidgetItem? Должен ли я добавить QTableWidgetItem в какой-то скрытый столбец?

В нашей текущей реализации используется indexAt(QtGui.qApp.focusWidget()) (см. Другой ответ на вопрос, упомянутый выше), который выглядит как извиняющийся обходной путь для меня.

Если я заменить кнопку с триггерной QTableWidgetItem как этот

rm_item = QtGui.QTableWidgetItem() 
rm_item.setFlags(QtCore.Qt.ItemIsUserCheckable | 
       QtCore.Qt.ItemIsEnabled) 

У меня есть QTableWidgetItem я могу использовать, чтобы вернуться к индексу строки. Но я не знаю, как поймать событие «проверено» или «щелкнуть», как я делаю с кнопкой. Все, что я нашел, это сигнал itemClickedQTableWidget, но тогда мне придется отфильтровывать все остальные виджеты.

Должно быть что-то очевидное, что мне не хватает.

Редактировать

Из того, что я прочитал here, я мог бы добавить как в QTableWidgetItem с SetItem и кнопки виджет с setCellWidget к одной и той же клетке. Для меня это не кажется таким естественным, но, видимо, это работает (сейчас я не могу проверить).

Думаю, я сделаю это. Добавьте кнопку, а также фиктивный QTableWidgetItem в одну и ту же ячейку, чтобы передать ссылку на строку.

Это как это должно быть?

Edit 2

Или, может быть QTableWidget не правильный виджет, и я должен быть с помощью Layout, как это было предложено here.

+0

Это не питон ответ, но я думаю, что мой C++ ответ [здесь] (http://stackoverflow.com/a/29177041/616644) может быть полезным. –

ответ

1

кажется, что с помощью макета, а не за столом, возможно, самый «правильный» ответ, но это может прийти с его собственными трудностями, как это видно в моем ответ на этот вопрос:

Если вы хотите продолжать использовать таблицу, несколько чище решение, чем добавление элементов манекена будет использовать persistent model index:

  button = QtGui.QPushButton(text, self.table) 
      self.table.setCellWidget(row, column, button) 
      index = QtCore.QPersistentModelIndex(
       self.table.model().index(row, column)) 
      button.clicked.connect(
       lambda *args, index=index: self.handleButton(index)) 

    def handleButton(self, index): 
     print('button clicked:', index.row()) 
     if index.isValid(): 
      self.table.removeRow(index.row()) 
+0

Еще раз спасибо @ekhumoro. Работает. Я просто использовал 'button.clicked.connect (lambda: self.handleButton (index))' –

0

Если я правильно понимаю ваш вопрос:

def set_button(self, row, col): 
    # create a push button 
    btn = QtGui.QPushButton('Remove row') 
    # connect to action 
    btn.clicked.connect(self.remove_row) 
    # set in cell 
    self.setCellWidget(row, col, btn) 


def remove_row(self): 
    # find what is clicked 
    clicked = QtGui.qApp.focusWidget() 
    # position 
    idx = self.indexAt(clicked.pos()) 
    # remove this row 
    self.removeRow(idx.row()) 
+0

Это то, что мы делаем уже, но я чувствую себя странно в использовании местоположения курсора здесь. При подключении сигнала мы знаем элементы строки, поэтому он немного искажен, чтобы потерять эту информацию намеренно, а затем искать позицию курсора после этого. Кроме того, если кнопка нажата с клавиатуры, метод не работает (см. [Принятый ответ здесь] (http://stackoverflow.com/questions/24649625/how-to-get-the-row-under-the-cursor- в-а-QTableWidget)). –

+0

Извините, я неправильно понял вопрос. AFAIK вы правы: с 'table.itemclicked' вы должны проверить состояние флажков. К настоящему моменту я не нашел другого способа. NB: взаимодействие клавиатуры с кнопками работает правильно со мной. – ngulam

+0

Я полагаю, если вы нажмете с клавиатуры, а указатель мыши на другой строке, 'indexAt (QtGui.qApp.focusWidget())' вернет индекс другой строки. Во всяком случае, см. Изменения, которые я внес на вопрос. Я думаю, что у меня есть приемлемое обходное решение (используйте как QTableWidgetItem, так и setCellItem в одной и той же ячейке) и ответ, который заключается в том, что я не должен использовать QTableWidget, но QLayout. –