Qt QTableWidget类方法setItem()bug问题解决

自己用QTableWidget来记录实时数据时,出现该问题,百度之后发现是因为在最初设置行数处(setRowCount()),设置的行宽不够,在对数据测试时,数据超出了设置行数,在调用相关setText()时,出现空指针导致程序崩掉。网上现存的解决方案中,是对该指针以及后续text进行空指判断,个人觉得这种实现方式治标不治本,所以本文会给出两种该bug的解决方式,以供参考。

 

空值判断

// 判断指向该item的指针是否为空 || 判断该item的text是否为空
if(ui->tableWidget_bsdl->item(i,j)==nullptr || ui->tableWidget_bsdl->item(i,j)->text().isEmpty())  
{    
}

该操作原理,可以参考这位博主的文章,讲得十分详细。

解释:
(1)因为C++逻辑或和逻辑与采用短路求值策略:对于逻辑或运算,当且仅当左侧运算对象为假时,才对右侧运算对象求值。
(2)当ui->tableWidget->item(i,j)==nullptr为真时,是空指针,此时左侧运算对象为真,不会对右侧运算对象求值,即,不会用空指针去访问->text(),不会判断ui->tableWidget->item(i,j)->text()是否为空,是安全的。
(3)当ui->tableWidget->item(i,j)==nullptr为假时,不是空指针,此时才对||的右侧运算对象求值,又因为它不是空指针,所以用它访问->text()是安全的。 

 

 动态设置最大行宽

static int ROW_COUNT = 20;//设置行宽

if(temp.count() > ROW_COUNT) //此处temp为vector,该vector存放了需要显示的数据
{
    ROW_COUNT = temp.count();
    this->setRowCount(ROW_COUNT);
}

//do else

获取到需要设置的行宽数据,每次保证ROW_COUNT为最大,并设置最大行宽,就不会出现空指针问题了。

 

利用QTableView实现

#ifndef LISTWIDGET_H
#define LISTWIDGET_H
#include 
#include 
#include 

class QStandardItemModel;
class TableView : public QTableView
{
    Q_OBJECT
public:
    TableView(QAbstractItemModel *model);
protected:
    virtual void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE;
    virtual QModelIndex moveCursor(CursorAction cursorAction, Qt::KeyboardModifiers modifiers) Q_DECL_OVERRIDE;
    void scrollTo (const QModelIndex & index, ScrollHint hint = EnsureVisible) Q_DECL_OVERRIDE;
};



class ListWidget: public QWidget
{
    Q_OBJECT
public:
    ListWidget(QTableWidget * parent = nullptr);
    ~ListWidget();


private:

 
    TableView *m_table_view;
    QStandardItemModel *m_model;
    QStringList headers;

};

#endif // LISTWIDGET_H
#include "ListWidget.h"
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 


TableView::TableView(QAbstractItemModel *model)
{
    setModel(model);
    setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    setHorizontalScrollMode(ScrollPerPixel);
    setVerticalScrollMode(ScrollPerPixel);
    //    verticalHeader()->setDefaultSectionSize(25); //配置行宽
    horizontalHeader()->setSectionResizeMode(0,QHeaderView::ResizeToContents);//配置大小模式
    horizontalHeader()->setSectionResizeMode(1,QHeaderView::Stretch);
    horizontalHeader()->setSectionResizeMode(2,QHeaderView::Stretch);

    setEditTriggers(QAbstractItemView::NoEditTriggers);
    setStyleSheet("QTableView { border: none;"
                  "selection-background-color: #999}");
}



void TableView::resizeEvent(QResizeEvent *event)
{
    QTableView::resizeEvent(event);
}

QModelIndex TableView::moveCursor(QAbstractItemView::CursorAction cursorAction, Qt::KeyboardModifiers modifiers)
{
    QModelIndex current = QTableView::moveCursor(cursorAction, modifiers);

    if (cursorAction == MoveLeft && current.column() > 0
            && visualRect(current).topLeft().x() < columnWidth(3) )
    {
        const int newValue = horizontalScrollBar()->value() + visualRect(current).topLeft().x()
                - columnWidth(0);
        horizontalScrollBar()->setValue(newValue);
    }
    if (cursorAction == MoveLeft)
    {
        const int newValue = horizontalScrollBar()->value() + visualRect(current).topLeft().x();

        horizontalScrollBar()->setValue(newValue);
    }
    return current;
}
void TableView::scrollTo(const QModelIndex &index, QAbstractItemView::ScrollHint hint)
{
    if (index.column() >= 0)
        QTableView::scrollTo(index, hint);
}

ListWidget::ListWidget(QTableWidget *parent) :QWidget(parent)
{
    m_model=new QStandardItemModel();

    headers << "ID" <<"距离"<<"角度";

    m_model->setHorizontalHeaderLabels(headers);
    QVBoxLayout *main_layout = new QVBoxLayout();

    m_table_view = new TableView(m_model);
    main_layout->addWidget(m_table_view);
    this->setLayout(main_layout);


    //    this->horizontalHeader()->setStyleSheet("QHeaderView::section{font: 15}");//设置表头背景和字体颜色
    this->setFont(QFont("黑体",8));

    m_timer = new QTimer(this);
    m_timer->start(500);//ms
    connect(this->m_timer,SIGNAL(timeout()),this,SLOT(clearListitem()));
}

ListWidget::~ListWidget()
{

}


//添加item代码

m_model->setItem(0,0,new QStandardItem(QString::number(it.key())));
m_model->item(0,0)->setTextAlignment(Qt::AlignHCenter|Qt::AlignVCenter);

利用qt本身的view-model结构来进行实现,这种实现方式,可以避免空指针的问题。

你可能感兴趣的:(Qt,qt5)