文档章节

关于QTableWidgetItem::setItemPrototype的理解

太空堡垒185
 太空堡垒185
发布于 2014/06/03 15:16
字数 958
阅读 147
收藏 0

在《C++ Gui Programming with Qt4》中第4章,SpreadSheet例子中,Cell继承自QTableWidgetItem类,SpreadSheet继承自QTableWidget类,在SpreadSheet中通过调用setItemPrototype方法设置SpreadSheet的项类--Cell,保证在用户点击时,自动生成Cell实例(instance)来保存用户输入的数据。

SpreadSheet::SpreadSheet(QWidget *parent) :    QTableWidget(parent),
    pActionActive(new QAction(this)),
    mIsSaved(false),
    mAutoRecalculated(false)
{
    setActionActive();

    //设置Cell类为SpreadSheet的项类.
    setItemPrototype(new Cell());

    connect(this, static_cast<void (SpreadSheet::*)(QTableWidgetItem*)>(&SpreadSheet::itemChanged),
            this, static_cast<void (SpreadSheet::*)()>(&SpreadSheet::somethingChanged));

    clear();
}

当用户在生成的类excel表格中点击项,则会自动生成Cell实例,保存用户的输入内容。

但是在第十章的CoordinateSettor例子中,在根据系统录入的10组坐标中,则是在后台直接创建item实例,填入在表格中的位置,然后再将坐标信息填写到item中,

将item实例填到表格中。

void TestTableWidget::addRow(){
    //pTableWidget为QTableWidget实例。
    int row(pTableWidget->rowCount());
    pTableWidget->insertRow(row);

    QTableWidgetItem* item0(new QTableWidgetItem());
    item0->setTextAlignment(Qt::AlignVCenter | Qt::AlignLeft);
    pTableWidget->setItem(row, 0, item0);

    QTableWidgetItem* item1(new QTableWidgetItem());
    item1->setTextAlignment(Qt::AlignBaseline | Qt::AlignRight);
    pTableWidget->setItem(row, 1, item1);

    pTableWidget->setCurrentCell(row, 0);
    
}

如果想向SpreadSheet那样自动生成item项,则必须调用其setItemPrototype方法。

TestTableWidget::TestTableWidget(const QList<QPointF>* coord,                                 QWidget *parent) :
    QWidget(parent),
    pTableWidget(new QTableWidget(0, 2, this))
{
    pCoordinates = coord;
    QStringList strList;
    strList.append(tr("X"));
    strList.append(tr("Y"));

    pTableWidget->setHorizontalHeaderLabels(strList);
    pTableWidget->setItemPrototype(new QTableWidgetItem());

    for (int row(0); row != pCoordinates->count(); ++row) {
        QPointF point = pCoordinates->at(row);
        addRow();
   
        pTableWidget->item(row, 0)->setText(QString::number(point.x()));
        pTableWidget->item(row, 1)->setText(QString::number(point.y()));
    }

    QVBoxLayout* vBoxLayout(new QVBoxLayout(this));
    vBoxLayout->addWidget(pTableWidget);
    setLayout(vBoxLayout);
}

发现执行到

pTableWidget->item(row, 0)->setText(QString::number(point.x()));

就会报告异常,怀疑setItemPrototype方法中只是制定当用户点击项时,系统自动创建项,而程序要往表格中填写内容时,必须创建项实例并添加到表格中。 后查看QTableWidget的api,setItemPrototype方法中要求实现QTableWidgetItem的derived class。感觉不能直接调用QTableWidgetItem的实例,故在此处创建class ItemClone,并实现clone方法。

QTableWidgetItem* ItemClone::clone() const{
    return new ItemClone();
}

然后将ItemClone 放到setItemPrototype方法中。这时候再运行程序就一切正常了。当表格中没有创建项实例时,用户手动点击表格,自动就会有项实例生成,保存信息。

以下是具体实现code

main

#include <QtWidgets>
#include "coordinatesetter.h"
#include "testtablewidget.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QList<QPointF> coordinates;
    coordinates << QPointF(0.0, 0.9)
                << QPointF(0.2, 11.0)
                << QPointF(0.4, 15.4)
                << QPointF(0.6, 12.9)
                << QPointF(0.8, 8.5)
                << QPointF(1.0, 7.1)
                << QPointF(1.2, 4.0)
                << QPointF(1.4, 13.6)
                << QPointF(1.6, 22.2)
                << QPointF(1.8, 22.2);
    //CoordinateSetter coordinateSetter(&coordinates);
    //coordinateSetter.show();
    TestTableWidget coordinateSetter(&coordinates);
    coordinateSetter.show();

    return app.exec();
}

显示表格的类:头文件

#ifndef TESTTABLEWIDGET_H#define TESTTABLEWIDGET_H

#include <QWidget>

QT_BEGIN_NAMESPACE
class QTableWidget;
QT_END_NAMESPACE

class TestTableWidget : public QWidget
{
    Q_OBJECT
public:
    explicit TestTableWidget(const QList<QPointF>* coord, QWidget *parent = 0);

private:
    void addRow();

private:
    QTableWidget* pTableWidget;
    const QList<QPointF>* pCoordinates;
};

#endif // TESTTABLEWIDGET_H

显示表格的类:实现文件

#include "testtablewidget.h"
#include <QTableWidget>
#include <QStringList>
#include <QTableWidgetItem>
#include <QVBoxLayout>

#include "itemclone.h"

TestTableWidget::TestTableWidget(const QList<QPointF>* coord,
                                 QWidget *parent) :
    QWidget(parent),
    pTableWidget(new QTableWidget(0, 2, this))
{
    pCoordinates = coord;
    QStringList strList;
    strList.append(tr("X"));
    strList.append(tr("Y"));

    pTableWidget->setHorizontalHeaderLabels(strList);
    pTableWidget->setItemPrototype(new ItemClone());
    //set pTableWidget to be disabled for changing item.
    //pTableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);

    for (int row(0); row != pCoordinates->count(); ++row) {
        QPointF point = pCoordinates->at(row);
        addRow();

        //pTableWidget->item(row, 0)->setData(Qt::DisplayRole, QString::number(point.x()));
        pTableWidget->item(row, 0)->setText(QString::number(point.x()));
        pTableWidget->item(row, 1)->setText(QString::number(point.y()));
    }

    QVBoxLayout* vBoxLayout(new QVBoxLayout(this));
    vBoxLayout->addWidget(pTableWidget);
    setLayout(vBoxLayout);
}

void TestTableWidget::addRow()
{
    //pTableWidget为QTableWidget实例。
    int row(pTableWidget->rowCount());
    pTableWidget->insertRow(row);

    ItemClone* item0(new ItemClone());
    item0->setTextAlignment(Qt::AlignVCenter | Qt::AlignLeft);
    pTableWidget->setItem(row, 0, item0);

    ItemClone* item1(new ItemClone());
    item1->setTextAlignment(Qt::AlignBaseline | Qt::AlignRight);
    pTableWidget->setItem(row, 1, item1);

    pTableWidget->setCurrentCell(row, 0);
}

QTableWidgetItem的derived类:头文件

#ifndef ITEMCLONE_H#define ITEMCLONE_H


#include <QTableWidgetItem>

class ItemClone : public QTableWidgetItem
{
public:
    ItemClone();

    virtual QTableWidgetItem* clone() const;
};

#endif // ITEMCLONE_H

QTableWidgetItem的derived类:实现文件

#include "itemclone.h"
ItemClone::ItemClone()
{
}

QTableWidgetItem* ItemClone::clone() const
{
    return new ItemClone();
}


如coder要测试是否自动创建项实例,而不是程序写的

可以将addRow方法修改为:

void TestTableWidget::addRow()
{
    //pTableWidget为QTableWidget实例。
    int row(pTableWidget->rowCount());
    pTableWidget->insertRow(row);
}

这样只是对表格插入行,但是每行中的项实例没有创建,只有运行程序,用户在表格中点击输入时,才会生成项对象。


© 著作权归作者所有

太空堡垒185
粉丝 9
博文 141
码字总数 47696
作品 0
西安
系统管理员
私信 提问
QTableWidget的使用和美工总结

基本外观设置 FriendTable->setFrameShape(QFrame::NoFrame); //设置边框 FriendTable->setHorizontalHeaderLabels(HeadList); 设置表头 FriendTable->setSelectionMode(QAbstractItemView:......

晨曦之光
2012/04/13
3.2K
0
QTableWidget 自定义排序

QTableWidget功能强大,可以在每个格子里添加自己的wiget部件。 如果想对这些自己添加的widget进行排序有两种方法。 一种是直接设置每个格子对应的QTableWidgetItem的值,因为QTableWidget默...

横云断岭
2010/10/20
0
0
QTableWidget 基本概念及功能使用

QTableWidget是QT程序中常用的显示数据表格的空间。QTableWidget是QTableView的子类,主要的区别是QTableView可以使用自定义的数据模型来显示内容(也就是先要通过setModel来绑定数据源),而Q...

barsoom
2012/10/24
909
0
QTableWidget点击表头按列排序

1、连接信号与槽: connect(tableWidget->horizontalHeader(), SIGNAL(sectionClicked(int)), this, SLOT(slot_sortByColumn(int))); 2、编写自己的排序槽函数:slot_sortByColumn(int idx)。......

科技探索者
2017/11/10
0
0
Qt编写自定义控件34-磁盘容量统计

一、前言 磁盘容量统计控件,说白了,就是用来统计本地盘符占用的容量,包括但不限于已用空间、剩余空间、总大小、已用百分比等,其中对应的百分比采用进度条显示,该进度条的前景色和背景色...

飞扬青云
07/21
22
0

没有更多内容

加载失败,请刷新页面

加载更多

CSS--列表

一、列表标识项 list-style-type none:去掉标识项 disc:默认实心圆 circle:空心圆 squire:矩形 二、列表项图片 list-style-img: 取值:url(路径) 三、列表项位置 list-style-position:...

wytao1995
今天
4
0
linux 命令-文本比较comm、diff、patch

本文原创首发于公众号:编程三分钟 今天学了三个文本比较的命令分享给大家。 comm comm 命令比较相同的文本 $ cat charabc$ cat chardiffadc 比如,我有两个文件char和chardiff如上,...

编程三分钟
今天
7
0
QML教程

https://blog.csdn.net/qq_40194498/article/category/7580030 https://blog.csdn.net/LaineGates/article/details/50887765...

shzwork
今天
5
0
HA Cluster之5

对于使用heartbeat v2版的CRM配置的集群信息都是保存在一个名为cib.xml的配置文件中,存放在/var/lib/heartbeat/crm/下。CIB:Cluster Information Base,由于xml文件配置不是那么方便,所以...

lhdzw
今天
6
0
玩转Redis-Redis基础数据结构及核心命令

  《玩转Redis》系列文章主要讲述Redis的基础及中高级应用,文章基于Redis5.0.4+。本文主要讲述Redis的数据结构String,《玩转Redis-Redis基础数据结构及核心命令》相关操作命令为方便对比...

zxiaofan666
今天
11
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部