QHeaderView行表头移动,Model数据跟着移动且可以保存
基于Qt6.4.5环境下的程序,能够通过移动QHeaderView 移动行表头,同时移动过程中model中的数据实时跟着移动,最后可以保存在XML中,第二次打开是移动后数据。
同时每一组treewidget下的结点都可以保存不同顺序的表头。(即:w_xxx下保存到表头顺序都可以不同,如果想要变成相同的顺序,可以选择手动拖动后保存或者见我下一篇文章,可以实现每一组下相同的结点名显示相同的表头顺序)
文章底部附免费资源链接,大家可以自行下载。
假设我们已经有了如图所示的界面布局,由QTreeWidget、QTableView、QTabWidget为主要控件组成

核心代码如下所示:
MainWindow.h
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->treeWidget,&QTreeWidget::itemPressed,this,&MainWindow::OnRightButtonClicked);
QTreeWidgetItem *root = ui->treeWidget->invisibleRootItem(); // 获取顶级根目录
int nChildNodeCount = root->childCount(); // 有几个子节点,我这里仅仅在root树下增加了2个子节点 Well Group Path 1 和 2
int nCurrentIndexRow = ui->treeWidget->currentIndex().row(); // 获取当前选中行的index
QString strNodeIndex = ""; //需要写入xml文件中的结点名称
for ( int i = 0; i < nChildNodeCount; ++i){
int nChild_i_ChildCount = root->child(i)->childCount() ;
strNodeIndex = QString::number(i) +" " + QString::number( nChild_i_ChildCount ); //根子节点索引 + 子节点的子节点个数
m_node_list.append( strNodeIndex ); // 将 当前对应的 父节点索引 和 当前结点的子节点个数 存入容器
}
create_xml_file(); // 开始就可以创建好目录树对应的XML格式数据
ui->treeWidget->expandAll();
}
create_xml_file() 创建xml
void MainWindow::create_xml_file()
{
QString strXmlFile = FILEPATH;
QFile file( strXmlFile);
if ( !QFile::exists(strXmlFile)){ //文件不存在
// 创建 xml 头部 信息
QDomDocument doc;
QDomProcessingInstruction instruction = doc.createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\"");
doc.appendChild(instruction);
QDomElement root = doc.createElement("root"); //创建根节点 root
doc.appendChild( root );
if ( !file.open( QIODevice::WriteOnly | QIODevice::Truncate)){
QMessageBox::critical(this,"Error","Fail To Open File ");
return ;
}
QDomElement node_Element;
for ( int i = 0; i < m_node_list.count(); ++i){
QString strNodeI = m_node_list.at(i);
QStringList nodeList = strNodeI.split(" ");
node_Element = doc.createElement("P_" + QString::number(i));
QDomElement child_node_Element;
for ( int nIndex = 0; nIndex < nodeList.at(1).toInt(); ++nIndex){
child_node_Element = doc.createElement("C_" + QString::number(nIndex));
QDomText strTemplateText = doc.createTextNode("NULL"); //创建元素文本
child_node_Element.appendChild(strTemplateText);
node_Element.appendChild(child_node_Element);
}
root.appendChild( node_Element );
}
QTextStream stream(&file);
stream.setEncoding(QStringEncoder::Utf8);
doc.save(stream, 4, QDomNode::EncodingFromTextStream); //保存到文件
file.close();
}
}
创建完的格式如下图所示,默认结点文本值都是 NULL

表头移动 核心代码
void WellMangerDialog::HeaderViewSectionMoved(int logicalIndex, int oldVisualIndex, int newVisualIndex)
{
qDebug() << "Section moved from" << oldVisualIndex << "to" << newVisualIndex<<"\t"<<"logicalIndex = "<<logicalIndex;
QString strCommand = QString("%1-%2").arg(oldVisualIndex).arg(newVisualIndex);
m_command_list.push_back(strCommand);
}
void WellMangerDialog::SaveBtnSlot()
{
QString strCommand = "";
for ( auto Command : m_command_list){
QStringList strCommandList = Command.split("-");
strCommand += Command +" ";
}
strCommand = strCommand.simplified(); //去掉首尾空格
QFile file("./table_column_order.xml");
if ( QFile::exists(FILEPATH)){ //文件存在
// 打开xml文件,修改xml数据
if ( !file.open(QFile::ReadOnly)){
QMessageBox::critical(this,"Error","Fail To Open File ");
return ;
}
QDomDocument doc;
if (!doc.setContent(&file)) {
QMessageBox::information(NULL, "提示", "操作的文件不是XML文件!");
file.close();
return;
}
file.close();
QStringList strXmlNode = m_xml_node.split(" "); // 0:root下的子节点个数 1:当前选中的父节点索引,2:当前结点索引
// 获取根节点
QDomElement root = doc.documentElement();
QDomNodeList NodeList = root.childNodes();
for ( int i = 0; i < NodeList.count();++i){
QString strNodeName = "P_"+strXmlNode.at(1);
QDomNode node = NodeList.at(i);
if (node.nodeName() == strNodeName){
QDomNodeList childNodeList = node.childNodes();
for ( int ci = 0; ci < childNodeList.count(); ++ci ){
QDomNode childNode = childNodeList.at(ci);
qDebug()<<childNode.nodeName();
if ( childNode.nodeName() == "C_"+strXmlNode.at(2) ){
QDomNode oldnode = childNode.firstChild();
childNode.firstChild().setNodeValue( strCommand );
QDomNode newnode = childNode.firstChild();
childNode.replaceChild(newnode,oldnode);
break;
}
}
break;
}
}
if (!file.open(QIODevice::WriteOnly))
return;
QTextStream out_stream(&file);
out_stream.setEncoding(QStringEncoder::Utf8);
doc.save(out_stream,4,QDomNode::EncodingFromTextStream); // 保存到文件
file.close();
}
}
移动后 记录的是表头的移动顺序 如下图所示


&spm=1001.2101.3001.5002&articleId=143105726&d=1&t=3&u=6db7920dd1c84ff59f08d251f6b3cd68)
686

被折叠的 条评论
为什么被折叠?



