做Demo

本文探讨了在Qt编程中解决QTableWidget中十字形高亮、QComboBox使用、删除行items、切片显示及加减附件成对出现的问题。针对QComboBox在单元格中的应用,提出了一夫一妻制度的解决方案,即每个单元格单独创建QComboBox,并解决了坐标计算和窗口缩放带来的问题。此外,还介绍了如何有效删除QTableWidget中的行items以及确保加减附件操作成对出现的逻辑实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一. 关于十字形高亮的解决方法:

使用选择视图QItemSelectionModel .

//将第row行与第column设置为高亮
void Widget::setHighlight(int row,int column)
{    
    QItemSelectionModel  *selectionModel =  tableWidget->selectionModel();
    QModelIndex top = tableWidget->model()->index(row, column, QModelIndex());
    QModelIndex bottom = tableWidget->model()->index(row, column, QModelIndex());
    QItemSelection selection(top, bottom);
    selectionModel->select(selection, QItemSelectionModel::Select|
                           QItemSelectionModel::Rows|QItemSelectionModel::Columns);
}

其中

QItemSelectionModel::select(const QItemSelection &selection, QItemSelectionModel::SelectionFlags command)

Flags可以进行位操作。

参考资料:http://www.aichengxu.com/jiagou/6197787.htm

二. 关于将QtableWidget 中QComboBox的问题。

一开始自己的想法跑偏了(每点击单元格则生成QComboBox,第二次点击则将第一次的那个隐藏掉),如果这样的话,一个8行4列的table 最多需要实例化32个QComboBox,内存的问题就很严重了,而且怎么隐藏掉第一个也不好处理。(隐藏掉其实蛮好处理的,用成员变量记录上一次的cell,在本次点击时让其隐藏掉就好了。同时本次点击前要看一下点击的cell有没有被隐藏的combox 。 2017/1/23 修改)

多谢老师的提醒:既然table中同一时刻只能显示一个QComboBox,那么不如将combox作为成员变量,整个表格就只有一个combox,这样一来不仅处理简单了,而且内存消耗也少了。

tableWidget->setCellWidget(row,column,combox);

下午发现这样做出现了一个问题, 一个单元格只能出现一次combox,暂时不知道是什么原因。
写了点东西调试一下很奇怪:

    QWidget* tmp = tableWidget->cellWidget(row,column);

    if(0 != tmp){
        qDebug()<<"EEEnable"<<tmp->isEnabled();输出true
        qDebug()<<"cellWidget" << tmp;  //输出 QComboBox(0xa1a9f0)
        qDebug()<<"1__Visible"<<tmp->isVisible();   //输出是  false
        tmp->setVisible(true);
        qDebug()<<"2__Visible"<< tmp->isVisible(); //输出还是 false
        //delete tableWidget->cellWidget(row,column);
    } else {
        qDebug()<<"--------" << combox;  //输出 QComboBox(0xa1a9f0)
        combox->setVisible(true);
        qDebug()<<"0__Visible"<<combox->isVisible(); //输出 false
        tableWidget->setCellWidget(row,column,combox);
    }

setVisible() 并没有发挥做用。

昨天下午问老师。老师说 一个combox 设置为多个cell 的widget 就好像一夫多妻制度一样不合时宜。 如果setcellwidget的话,最好是新建一个combox,每个cell里面都有自己的combox.一夫一妻制度。

昨晚问了一下Qt论坛的坛主,给的解释是这样的:

每个cell默认是有部件的,就是个label或lineEdit,现在用comboBox替换了那个label,就相当于把以前的label给delete掉了,那个cell都没有部件了,就变成不可选取了,所以你无法再向其中添加部件。

但是我在构造函数里加了段调试代码:

    QWidget* tmp = tableWidget->cellWidget(1,1);
    qDebug()<<"tmp"<<tmp;       // 输出  tmp QWidget(0x0)
//    qDebug()<<"enable"<<tmp->isEnabled();    
//这句不注释掉会程序崩溃,应该是因为空指针的缘故。
    if(0 != tmp){
        qDebug() << 1;
    }else{
        qDebug()<<0;
    }

这样看的话 默认状况下,cell里面应该是空才对。

另外一种解决方式是这样的:
计算一下cell的坐标,让combox 在cell那个位置显示。
一开始找到个系统自带的方法:

QRect rect = tableWidget->visualItemRect(tableWidget->item(row,column));

Returns the rectangle on the viewport occupied by the item at item.

但是问题在于 当item为空时,tableWidget->item(row,column)返回的是0。自然而然的返回的坐标就不对了。 因此这个方法不能用。
那就只能自己计算坐标了。行、列、行高、列宽,在加上tableWidget的坐标和主窗口坐标的一点偏差,就能算出来了。不过这种做法的健壮性就不知道怎样了。

    int y = (row + 2)*highRow - (highRow/2);
    int x = (column + 2)*widthCol - (widthCol/2);
   // qDebug()<<"1_comboxVisible"<<combox->isVisible();    
    combox->setCurrentIndex(0);   
    combox->setVisible(true);
   // qDebug()<<"2_comboxVisible"<<combox->isVisible();
    combox->move(x,y);

这样实现,暂时并没有发现什么问题,希望能找到更好的方法。

这样做有问题: 扩大缩小窗口,就 不贴合了. 改用为每个cell建立combox得了。

四. 删除某一行的items

解决方式:
选定该行,然后遍历删除。

tableWidget->selectRow(row);
foreach (QTableWidgetItem *item, tableWidget->selectedItems()) {
                delete item;
            }

参考博客:http://www.educity.cn/wenda/190266.html

五.关于切片时显示

设计说明:使用QMessageBox 给用户显示切片牙齿。

void Widget::cutpiece()
{
    int col = tableWidget->currentColumn();
    int row = tableWidget->currentRow();
    tableWidget->setItem(row,col,new QTableWidgetItem(QIcon(":/images/22.png"),"cutpiece",1));
    QMessageBox::information(this,"CUTPIECE",tr("cut between %1 and %2").arg(row).arg(row+1));
}

五.关于加附件减附件成对出现

序列只能是 加减加减加减…且操作只能在序列最后添加。
在进行了加操作后,需要提醒用户设置减操作;
由于每次进行操作都保证了上面的条件,因此下一次操作依然满足条件。这样的话只需要判断距离(row,col)左右两侧是否存在附件并做相应操作就好了。
按照上面的思路写:
第一步.判断 (row,col) 到 (row,maxCol)如果有加减操作,则一切操作都不合法。
第二步.判断(row,col)到(row,0)第一个遇见的操作。是加操作则只能进行减操作,是减操作则只能进行加操作。

由于有三种附件类型,因此需要进行匹配。
可以将菜单中非法操作设置为不可选,这样用户无法进行点击。从而避免产生不成对现象。

有两种方式,
1.牺牲时间: 每次右击都检测该行的加减附件的操作。
2.牺牲空间: 建立新类Position 其成员变量有 ,操作类型(加,减),位置)
建立一个三个 Position 类型的数组,分别保存每一颗牙齿每一种附件的最后一个的操作类型以及位置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值