2015-11-13 2 views
2

У меня есть QTableWidget, у которого QPushButtons есть вид ячеек. Я использую эти кнопки как средство для удаления строки из таблицы. У меня проблема, когда QPushButtons можно случайно переместить из центра в своей ячейке. На изображении ниже показано, что происходит.Виджет ячейки QTableWidget не отображается правильно при удалении последней строки

enter image description here

Это происходит в конкретном случае, когда пользователь имеет 1) сделал выбрана ячейка в последней строке таблицы, 2), что ячейка содержит кнопку удаления, и 3) вертикальная полоса прокрутки перемещается так, что последняя строка частично видима.

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

Edited включить четкий выбор, прежде чем вызов removeRow:

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow), 
    signalMapper_(new QSignalMapper(this)), 
    table_(new QTableWidget()) 
{ 
    ui->setupUi(this); 
    this->setFixedSize(200,300); 

    QGridLayout *layout = new QGridLayout(ui->centralWidget); 
    layout->addWidget(table_); 

    table_->setRowCount(0); 
    table_->setColumnCount(1); 

    // if you comment out the following line then the problem is not present 
    table_->setSelectionMode(QAbstractItemView::SingleSelection); 

    for (int i = 0; i < 20; i++) { 
     table_->insertRow(i); 
     QPushButton *button = new QPushButton("Delete"); 
     connect(button, SIGNAL(clicked(bool)), signalMapper_, SLOT(map())); 
     signalMapper_->setMapping(button, i); 
     table_->setCellWidget(i, 0, button); 
    } 
    connect(signalMapper_, SIGNAL(mapped(int)), this, SLOT(DeletePressed(int))); 

    table_->setCurrentCell(19,0); 
} 

MainWindow::~MainWindow() 
{ 
    delete ui; 
} 

void MainWindow::DeletePressed(int row) 
{ 
    table_->clearSelection(); // <- added clear selection before remove row 
    table_->removeRow(row); 
} 

Я думаю, что проблема связана с QTableWidget пытаясь сохранить видимую выбранную ячейку, когда новый выбор сделан. Я попробовал оба ответа, размещенные here, но не решил мою проблему.

Если бы кто-нибудь мог сказать мне, как решить эту проблему, я был бы признателен за помощь.

ответ

1

У меня была аналогичная проблема давно с QtreeWidget и я решил ее callig защищенный метод updateGeometries().

Если вы не специализировались QTableView, вы не можете просто вызвать эту функцию (как она защищена), так вот уловка, чтобы просто сделать это:

class MyQTableView : public QTableView 
{ 
public: 
    inline void publicUpdateGeometries() { updateGeometries(); } 
}; 

void MainWindow::DeletePressed(int row) 
{ 
    table_->clearSelection(); // <- added clear selection before remove row 
    table_->removeRow(row); 

    // call the protected method QTableView::updateGeometries() 
    ((MyQTableView*) table_)->publicUpdateGeometries(); 
} 

Надеется, что это решит вашу проблему.

+0

Работал как шарм. Благодарю. – Stanton

+0

Добро пожаловать. Кстати, я только что сообщил об ошибке Qt, поэтому, надеюсь, это может быть исправлено в более поздних версиях Qt. https://bugreports.qt.io/browse/QTBUG-49548 – jpo38

0

Попробуйте ui->tableWidget->clearSelection();

+0

Где я могу поместить это в свой код? Я сделал слот под названием 'DeletePressed (int row)', который я подключил к signalMapper. В слоте я добавил ваш 'clearSelection()', за которым следует вызов 'removeRow (row)', но это не решило проблему. – Stanton

+0

Я думаю, вы должны называть 'clearSelection' перед' removeRow (строка) ' – Szymson

+0

Я внес изменения, как вы предложили, но это не решило мою проблему. Пожалуйста, просмотрите отредактированный код, чтобы увидеть, что я сделал это по вашему желанию. – Stanton

0

Это происходит только при добавлении полосы прокрутки. Чтобы решить эту проблему, вам нужно установить setvrticalscrollbarpolicy, чтобы прокрутить панель, а затем удалить строку и добавить прокрутку по мере необходимости с помощью setverticalbarpolicy. Это решит вашу проблему. Я сделал то же самое.

Смежные вопросы