zoukankan      html  css  js  c++  java
  • QTableWidget表格合并若干问题及解决方法

    Qt提供 QTableWidget作为表格的类以实现表格的基本功能,表格中所装载的每一个单元格由类QTableWidgetItem提供。这是基于表格实现 Qt提供的一个基础类,若想实现定制表格和单元格的功能则需要派生重写,使用Qt经典的MV结构 QTableView+QAbstractItemMode来实现。

    关于QTableWidget+QTableWidgetItem使用方法简介:

    通常在使用这对组合以实现表格基本功能时,通常的做法是:

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    示例代码一:

    QTableWidget*  tableWidget = new QTableWidget;   

    tableWidget->setRowCount(11);                    // 设置表格的行数

    tableWidget->setColumnCount(11);                 // 设置表格的列数

    // 为表格的每一行每一列设置一个可以装载数据的item

    for(int nRow = 0; nRow < 11; nRow++)

    {

           for(int nColumn = 0; nColumn < 11; nColumn++);

           {

                  QTableWidgetItem* item = new QTableWidgetItem;

                         tableWidget->setItem(nRow, nColumn, item);

    }

    }

    // 通过索引访问表格中的单元格并赋值

    QTableWidgetItem* item = tableWidget->itemAt(3, 3);

    item->setText(“MyTableItem”);

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    OK!如果你仅仅是操作表格的单元格上述代码没有问题,但是如果你一旦涉及到表格的单元格合并时,这样操作表格就会出问题!

    下面是笔者在开发过程中实现表格合并时遇到的一些问题及相关的解决方法:

    问题一:如果按照示例代码一方式创建表格和单元格进行表格合并时

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    tableWidget->setSpan(0, 0, 1, 11);

    QTableWidgetItem*  itemGet = tableWidget->itemAt(0, 0);

    itemGet->setTextAlignment(Qt::AlignHCenter);

    itemGet->setText(“MyTableItem(0, 0)”);

    /* OK!上述代码没问题,实现第一行单元格的合并和设置text */

    itemGet = NULL;

    itemGet = tableWidget->itemAt(1, 1);

    itemGet->setTextAlignment(Qt::AlignHCenter);

    itemGet->setText(“MyTableItem(1, 1)”);

    /* Error!这里就出问题了,itemAt(1, 1)返回的仍然是itemAt(0, 0)所指向的单元格。就是由表格合并函数tableWidget->setSpan()所带来的问题,表格合并使得itemAt()等相关的索引函数出现问题。(具体原因还不太清楚)*/

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    解决方法:

    (1) 既然setSpan()函数破坏了itemAt()的索引,我们可以通过重新建立新的item的方式进行访问方法如下:

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    QTableWidgetItem*    newItem = new QTableWidgetItem;

    tableWidget->setItem(1, 1, newItem);

    newItem->setTextAlignment(Qt::AlignHCenter);

    newItem->setText(“MyTableItem(1, 1)”);

    /* 这样就可以实现表格其它位置单元格的赋值操作 */

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    (2) 不在创建QTableWidget时为单元格动态创建QTableWidgetItem,而是在用到某个单元格是再动态创建QTableWidgetItem。(推荐使用这种方法,避免内存泄露)

    问题二:和问题一的情况相同都是由于索引而产生的,这次是由于selectedRange()索引错误而产生。

    使用TableWidget生成表格后,希望通过鼠标的选择合并单元格,这时会发现只有第一次调用selectedRange()能正确返回鼠标所选择的单元格的范围并执行合并成功,第二次以后selectedRanged()返回的永远是鼠标选择范围的第一单元格。

    解决方法:使用函数selectedRanges()。该函数将返回QList对象,里面包含了被鼠标选择的所有单元格的位置,这样我们就可以实现多次合并。代码如下:

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    tableWidget->setSpan(tableWidget->selectedRanges().first().topRow(),

    tableWidget->selectedRanges().first().leftColumn(),

    tableWidget->selectedRanges().last().bottomRow() –

                               tableWidget->selectedRanges().first().topRow() + 1,

    tableWidget->selectedRanges().last().rightColumn() -

    tableWidget->selectedRanges().first().leftColumn() + 1);

    http://blog.chinaunix.net/uid-22159621-id-3049697.html

    ----------------------------------------------------------------------------------

    Qt:多次合并单元格的时要注意
    如果一个QTableView使用setSpan合并后,数据更新后,还要继续使用setSpan再次合并(主要是要对全表格进行重新的单元格合并,已经合并过的地方行列又要重新进行新的合并,因为数据已经更新),这时不能直接使用setSpan,而是要先把QTableView的row还原为原来没有合并行列的情形,再次使用setSpan,否则显示很可能就会发生错误:
    if (model != 0) {
    // 恢复QTableView的为未合并前的样子
    for (int i = 0; i < model->rowCount(); ++i) {
    ui->tableView->setSpan(i, 1, 1, 1);
    ui->tableView->setSpan(i, 10, 1, 1);
    }
    }

    // 合并单元格
    if (currentRow - firstRow != 1) {
    ui->tableView->setSpan(firstRow, 1, rowSpan, 1);
    ui->tableView->setSpan(firstRow, 10, rowSpan, 1);
    }

    http://www.cppblog.com/biao/archive/2009/12/11/102955.html

  • 相关阅读:
    Ruby窗口程序
    RubyWin32Api Win32OLE
    Ruby网络服务
    Ruby 文件处理
    Ruby基础数据类型
    Ruby基础类型,动态特性,代码块
    Ruby类,模块1
    Ruby准备工作
    js变量作用域
    ExecuteStoreQuery
  • 原文地址:https://www.cnblogs.com/findumars/p/5422995.html
Copyright © 2011-2022 走看看