Qt笔记-QTableWidget
i) Qt的QTableWidget初始化完成的QTableWidgetItem,如果删除了其指针,那么被删除的指针==nullptr。
此时,如果QTableWidget的对应单元格所在行还存在的话,用户可以在被删除单元格指针对应单元格输入值,实际上就是被删除的指针重新分配了空间。
但是如果继承QTableWidget,那么被删除的指针!=nullptr,不过调用被删除的指针的.data()等函数会出现内存访问错误。由此可以看出,QTableWidget似乎内置 某种机制:如果QTableWidgetItem指针被删除,那么该指针具备自动重新被分配空间的能力。
表现:如果未继承QTableWidget,那么该指针为空,但随时可以接受用户输入,这样就分配了空间;
如果继承QTableWidget,那么该指针不为空,但是其data参数为非法,同时无法访问其内存空间。
(第二种情况经验证是因为此时currentItem指向被删除的指针)。
这里也隐含着QTableWidget.insertRow(int row)官方说明的内在含义:插入的行是空的,指针为空,但是随时接受分配了空间的QTableWidgetItem。
ii) 如果在*.ui文件中设定了QTableWidget的行与列, 只要行列交叉形成的QTableWidget单元格没有输入字符, 那么此时QTableWidget单元格对应的QTableWidgetItem就不存在。
同理, 如果使用代码执行setRowCount(...)和setColumnCount(...), 效果与上面ui设定方法产生的效果一致。
注意:
这里的"单元格(没有)输入字符"指用户在程序执行时触发单元格的EditTrigger, 比如:即使双击单元格, 出现字符输入定位符然后就ui焦点就离开单元格, 这种情况下QTableWidget也会默认生成一个QTableWidgetItem在单元格那里;但是如果用户在QTableWidget的没有分配QTableWidgetItem的单元格使用setText("<str>"), 则不会产生自动生成QTableWidgetItem的效果。
iii) 在*.ui文件中编辑的"行"与"列"实际是QTableWidget的水平header和垂直header。
iv) 如果需要使用setItem(int row, int column, QTableWidgetItem *item), 那么需要确保在这之前有执行过insertRow(int row)公有成员函数,否则QTableWidget显示不正常。
v) 如果QTableWidget没有setRowCount和setColumnCount,那么即使insertRow也无效。所以只要setRowCount()之后就可正常insertRow了。
vi) 和容器不同,容器添加了局部变量后,一旦容器离开局部变量作用域,那么容器内之前的局部变量依然有值。但是QTableWidget一旦添加非指针类型的QTableWidgetItem,离开QTableWidgetItem的作用域后就无法找到QTableWidgetItem了。
vii) 这个类的clear()公有成员函数会把header一起删除, 但是不会释放内部QTableWidgetItem指针指向的内存空间。
此时如果用户通过"在单元格内输入字符的方式"令QTableWidget重新自动生成QTableWidgetItem的话, 重新生成的QTableWidgetItem的地址和原先占用的QTableWidgetItem地址是不一致的。
然而, 由Qt文档可以看到一旦QTableWidgetItem指针被set入QTableWidget, QTableWidgetItem指针的所有权就被QTableWidget取到了, 这个时候即使人为delete QTableWidgetItem指针, QTableWidgetItem指针也不会释放占用空间。
进一步的试验发现: 使用QTableWidget::takeItem()取出QTableWidgetItem后, 人为delete QTableWidgetItem指针也不会释放占用空间。clear(), clearContents()加setRowCount(...)都是如此。
目前我没有发现可以取消这个QTableWidgetItem被QTableWidget占用所有权的接口。
实验表明似乎只要Qt的控件被插入某个父控件或ui, 这个控件及其数据的所有权就被接管了, 然后再也无法取消所有权, 一旦无法取消所有权, 其指针仍然会指向某个有效的内存空间。所以, QTableWidgetItem一旦其所有权被接管, 那么Qt就开始自动管理QTableWidgetItem的存储空间了。
结果就是: Qt程序占用内存会越来越多, 除非整个Qt程序被终止。
viii)clearContents()公有成员函数只会删除除header外的item, 但是QTableWidget的rowCount和columnCount维持不变。
ix) 这个类使用setDragDropMode就可以起用其默认的拖拽功能。但是默认QTableWidget的默认拖拽功能无法个性化的。
即使从QTableWidget派生某个类, 同时重定义dropEvent(...)也无法从事件的mimeData()获取当前被拖拽的文本。
x) QTableWidget如果重设列标题,必须在setColumnCount()之后执行, 否则列标题设置无效。