QTableWidget中的表格显示图片有几种方式:

需要先将图片加载为资源。

1.直接在创建QTableWidgetItem的时候创建,如

tableWdiget->setItem(0,1,new QTableWidgetItem(QIcon(":/image/cpu")," "));

2.通过在item中创建一个label,通过label的setPixMap函数来显示图片:

QLabel *label = new QLabel("");
label->setPixmap(QPixmap(":/image/grid").scaled(30,30));
ui->matrixViewTable->setCellWidget(0,i,label);

3.通过继承 QStyledItemDelegate类使用委托来实现item中显示图片:

class QPixmapItemdele : public QStyledItemDelegate
{
public:
    QPixmapItemdele(QObject* parent = 0):QStyledItemDelegate(parent){ }
    //在委托类的paint中画图
    virtual void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        if(index.data(Qt::DisplayRole).canConvert<QPixmap>())
        {
            QPixmap pix = index.data(Qt::DisplayRole).value<QPixmap>();
            painter->drawPixmap(option.rect,pix);
        }
        QStyledItemDelegate::paint(painter,option,index);
    }
};

然后为tablewidget设置委托,后面就可以设置具体的某项的图片:

  ui->matrixViewTable->setItemDelegate(new QPixmapItemdele());
       //以下是设置第一行的所有列的图片
    for(int i=0; i<ui->matrixViewTable->columnCount(); i++)
    { 
        QTableWidgetItem *item = new QTableWidgetItem();
        ui->matrixViewTable->setItem(0,i,item);
        item->setData(Qt::DisplayRole,QVariant::fromValue<QPixmap>(QPixmap(":/image/grid").scaled(30,30)));
    }

以上三种方法,法一直接在item上创建Icon,则表中每个Item表示为左边icon,右边为icon对应的text,即使text为空,也会留出很大的空间出来,导致左边的icon很小,

可以用以下语句来设置左边图标大小:

ui->matrixViewTable->setIconSize(QSize(30,30));

但是右边还是有text留出来的空间,如果想让icon充满整个item,则此方法没法达成。

法二通过item中创建label来setPixMap的方式可以让icon充满整个item,但是显示出来的icon用鼠标点击不会有选择动作发生,或者也许可以处理点击事件(未试过,不知是否能行)。

法三继承委托能够让图片充满整个item,同时选择图片时,会出现选择框,不至于像法二一样点击了没有任何反应。

以下是法三QWidgetTable使用委托的代码(委托类已在上面给出):

ui->matrixViewTable->setItemDelegate(new QPixmapItemdele());
    int colcount = 17;
    int rowcount = 2;
    ui->matrixViewTable->setColumnCount(colcount);
    ui->matrixViewTable->setRowCount(rowcount);
    ui->matrixViewTable->horizontalHeader()->setVisible(false);
    ui->matrixViewTable->verticalHeader()->setVisible(false);
    ui->matrixViewTable->setSelectionMode(ui->matrixViewTable->NoSelection);
    ui->matrixViewTable->setEditTriggers(ui->matrixViewTable->SelectedClicked);
    ui->matrixViewTable->setShowGrid(false);
    ui->matrixViewTable->setFrameShape(QFrame::NoFrame);
    const int width = 30;
    for(int i=0; i<ui->matrixViewTable->columnCount(); i++)
    { 
  ui->matrixViewTable->setColumnWidth(i,width);
        //设置第8列为间隔行,不允许点击或选择
        if(i==8)
        {
            QTableWidgetItem *itm1 = new QTableWidgetItem();
            ui->matrixViewTable->setItem(0,i,itm1);
            itm1->setFlags(Qt::NoItemFlags);
            QTableWidgetItem *itm2 = new QTableWidgetItem();
            ui->matrixViewTable->setItem(1,i,itm2);
            itm2->setFlags(Qt::NoItemFlags);
            continue;
        }
        QTableWidgetItem *item = new QTableWidgetItem();
        ui->matrixViewTable->setItem(0,i,item);
        item->setData(Qt::DisplayRole,QVariant::fromValue<QPixmap>(QPixmap(":/image/grid").scaled(30,30)));
        QTableWidgetItem *item2 = new QTableWidgetItem();
        ui->matrixViewTable->setItem(1,i,item2);
        item2->setData(Qt::DisplayRole,QVariant::fromValue<QPixmap>(QPixmap(":/image/grid").scaled(30,30)));
    }
    ui->matrixViewTable->setColumnWidth(8,15);

以下是运行生成的效果,每个表格中间是一个图片:

使用委托能够在表格中显示图片,但是如果要在表格中画图,比如画线,则使用委托画出来的图会把线覆盖掉,也就是线会有画出来,但是看不到,实际是画了在图的下面。

在表格中显示图片还有第4种方法,安装事件过滤器,然后在过滤器函数EventFilter()函数中进行画图。因为此处用到的QTableWidget是Widget中的一个控件,因此可以安装事件过滤器,让Widget监视QTableWidget中的事件。代码如下,在类中重写QWidget类的eventFilter函数,然后创建表格时,每一列就创建为空,在evenFilter函数中检测到paint事件时才进行将图片画到表格中。

class MatrixView : public QWidget
{
    Q_OBJECT
public:
    explicit MatrixView(QWidget *parent = 0);
    ~MatrixView();
public:
    bool eventFilter(QObject *, QEvent *); 
private:
    void InitTableWidget();
    bool IsMouseInTableWidget(QEvent *event, QPoint &p);
    void SetPointToCenter(QPoint&);
private:
    Ui::MatrixView *ui;
    QPoint m_beginP;
    QPoint m_endP;
    bool m_bmove;
    bool m_brelease;
};

//以下是在构造函数中创建表格,表格其他部分与上面代码一样

//必须是tablewidget的viewport注册事件过滤才会有鼠标事件,如果是tablewidget注册,则收到除了鼠标事件外的其他事件,也就是鼠标事件收不到
 ui->matrixViewTable->viewport()->installEventFilter(this);
m_bmove = false;
m_brelease = false;
for(int i=0; i<ui->matrixViewTable->columnCount(); i++)
    { 
        ui->matrixViewTable->setColumnWidth(i,COL_WIDTH);
        //设置第8列为间隔行,不允许点击或选择
        if(i == NULL_COL)
        {
            QTableWidgetItem *itm1 = new QTableWidgetItem();
            ui->matrixViewTable->setItem(0,i,itm1);
            itm1->setFlags(Qt::NoItemFlags);
            QTableWidgetItem *itm2 = new QTableWidgetItem();
            ui->matrixViewTable->setItem(1,i,itm2);
            itm2->setFlags(Qt::NoItemFlags);
            continue;
        }
        QTableWidgetItem *item = new QTableWidgetItem();
        ui->matrixViewTable->setItem(0,i,item);
        //使用委托显示图片
        //item->setData(Qt::DisplayRole,QVariant::fromValue<QPixmap>(QPixmap(pixmap).scaled(30,30)));
        QTableWidgetItem *item2 = new QTableWidgetItem();
        ui->matrixViewTable->setItem(1,i,item2);
        //item2->setData(Qt::DisplayRole,QVariant::fromValue<QPixmap>(QPixmap(pixmap).scaled(30,30)));
    }

//在eventFilter中获取tablewidget的鼠标按下、移动,释放事件,进行画线,在画线之前进行画图。此处画图的效果与法三的效果一样,且可以在图上面画线。如果不需要处理鼠标事件,此处可以忽略3个鼠标事件的判断。

bool MatrixView::eventFilter(QObject *object, QEvent *event)
{
 //   qDebug("%s type:%d",object->objectName().toStdString().c_str(),event->type());
    if(object->objectName()!=QString("qt_scrollarea_viewport"))
    {
        return QWidget::eventFilter(object,event);
    }
    if(event->type() == QEvent::MouseButtonPress)
    {
        if(IsMouseInTableWidget(event,m_beginP))
        {
            m_endP = m_beginP;
            update();
        }
    }
    if(event->type() == QEvent::MouseButtonRelease)
    {
        IsMouseInTableWidget(event,m_endP);
        m_brelease = true;
        SetPointToCenter(m_endP);
        update();
    }
    if(event->type() == QEvent::MouseMove)
    {
        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
        //不进行判断左右键,如果判断左右键,会导致m_endP有时无值,画出的线断断续续
        m_endP = mouseEvent->pos();
        m_bmove = true;
        update();
    }
    if(event->type() == QEvent::Paint)
    {
        QPainter paint(ui->matrixViewTable->viewport());
        //使用paint事件在表格中画图
        int w = COL_WIDTH;
        int h = ui->matrixViewTable->rowHeight(0);
        for(int i=0; i<ui->matrixViewTable->columnCount()-1; i++)
        {
            int x = i>=NULL_COL ? i*COL_WIDTH+NULL_COL_WIDTH : i*COL_WIDTH;
            int y = 0;
            int y1 = ui->matrixViewTable->rowHeight(0);
            QPixmap pix(":/image/grid");
            paint.drawPixmap(QRect(x,y,w,h),pix);
            QPixmap pix1(":/image/grid");
            paint.drawPixmap(QRect(x,y1,w,h),pix1);
        }
        //在表格中画线,线随鼠标动
        if(m_bmove)
        {
            QPen pen(Qt::black,5);
            paint.setPen(pen);
            SetPointToCenter(m_beginP); //取得鼠标最接近项的中心点
            paint.drawPoint(m_beginP);
            QPen pen1(Qt::black,3);
            paint.setPen(pen1);
            paint.drawLine(m_beginP,m_endP);
            QPen pen2(Qt::black,5);
            paint.setPen(pen2);
            paint.drawPoint(m_endP);
        }
        if(m_brelease)
        {
            m_bmove = false;
            m_brelease = false;
        }
    }
    //此处必须返回基类的eventFilter,以让基类有机会进行处理其他事情,否则单单返回true,Qtablewidget上面将无其他东西显示
    return QWidget::eventFilter(object,event);
}
//判断鼠标按下的点是否在表格内,可无需关注
bool MatrixView::IsMouseInTableWidget(QEvent *event, QPoint &point)
{
    if(event->type() == QEvent::MouseButtonPress  ||
       event->type() == QEvent::MouseButtonRelease||
       event->type() == QEvent::MouseMove)
    {
        QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
        if(mouseEvent->button() == Qt::LeftButton)
        {
            QPoint p = mouseEvent->pos();
            //检查鼠标位置是否点在列表的项中,需要考虑中间空白间隔的那列除外
            int col = p.x()/COL_WIDTH>=NULL_COL ? (p.x()+NULL_COL_WIDTH)/COL_WIDTH : p.x()/COL_WIDTH;
            int row = p.y()/ui->matrixViewTable->rowHeight(0);
            if(col<ui->matrixViewTable->columnCount() && row<ui->matrixViewTable->rowCount())
            {
                if(col != NULL_COL)
                {
                    point = p;
                    return true;
                }
            }
        }
    }
    return false;
}
//取得最靠近该点的项的中心点,可无需关注
void MatrixView::SetPointToCenter(QPoint &point)
{
    int x = 0;
    if(point.x()/COL_WIDTH < NULL_COL)
    {
        x = point.x()/COL_WIDTH*COL_WIDTH + COL_WIDTH/2;
    }
    else
    {
        //因为第8列是空列,所以要排除这一列,先将point所在的x坐标减去8列前的部分,得到超出8列后的部分,就可以按照取中心点的方法取得这超出后部分的中心点,再加上8列前部分的位置,就得到最终的中心点
        int null_col_end_x = NULL_COL*COL_WIDTH + NULL_COL_WIDTH;
        x = null_col_end_x + (point.x()-null_col_end_x)/COL_WIDTH*COL_WIDTH + COL_WIDTH/2;
    }
    int h = ui->matrixViewTable->rowHeight(0);
    int y = point.y()/h*h + h/2;
    point = QPoint(x,y);
}

效果 图:(图中直线上的折线是抗锯齿,如果线宽小的话就不会这么明显)

QTableWidget中表格显示图片相关推荐

  1. vue表格显示图片,采用element ui实现

    项目场景: vue表格显示图片,采用element ui实现 <template><el-table :data="tableData" style=" ...

  2. 如何在ASP.Net 中把图片存入数据库

    介绍 可能有很多的时候,我们急需把图片存入到数据库当中.在一些应用程序中,我们可能有一些敏感的资料,由于存储在文件系统(file system)中的东西,将很容易被某些用户盗取,所以这些数据不能存放在 ...

  3. 在DataGrid中显示图片

    兼谈 DadaGrid 模板列的创建 DadaGrid 是 ASP.NET 编程中一个很重要的控件,其优良的可定制功能为提高它的表现力提供了极大的方便.除了与数据源直接绑定以外,我们还可以通过列绑定模 ...

  4. matlab读取一个文件的图片大小,Matlab读取文件夹中子文件夹中的图片并修改尺寸...

    今天被师兄问到如何利用matlab批处理图片,觉得很简单嘛 就让他去百度 结果只百度到处理文件夹中图片的程序 好吧 这里放上如何处理文件夹中子文件夹的图片 现状:在一个名为casia的文件夹中,里面有 ...

  5. java 移动页面中的图片上传_移动端图片操作——上传

    上传我们一般都是用"input[type=file]"控件.当你用此控件时,你就授权了网页和服务器访问对应的文件,就可以得到File对象. 友情提示在,在Android手机webv ...

  6. UIWebView保存网页中的图片(转载)

    现在H5混合原生开发的方式越来越流行,也就要用到UIWebView控件.在开发过程中,我们可能会遇到一个需求,要求我们保存网页上的图片,当用户点击图片的时候,就可以让用户选择是否下载图片. 在系统自带 ...

  7. 将ImageVIew中的图片保存到本地相册中

    2019独角兽企业重金招聘Python工程师标准>>> 一:将ImageView中的图片转换成Bitmap 二:将Bitmap 转换成二进制,写入本地 三:用广播通知相册进行更新相册 ...

  8. R语言ggplot2可视化在可视化的接种中插入图片、添加图片实战

    R语言ggplot2可视化在可视化的接种中插入图片.添加图片实战 目录 R语言ggplot2可视化在可视化的接种中插入图片.添加图片实战

  9. word 数组 转 指针_Word之VBA丨文档中的图片怎样批量加边框?

    不称深度指南,只愿浅度指北 很多时候,我们在 Word 中添加的图片,大部分都是类似下面这样"白底黑图"的: 如果图片内容是一段文字,就更加大了我们对文章的理解难度. 这时,我会给 ...

最新文章

  1. 细述 Java垃圾回收机制→Java Garbage Collection Monitoring and Analysis
  2. OperationalError: (1044, Access denied for user ''@'localhost' to database 'mydb')
  3. python第二章上机实践_第二章上机实践报告
  4. [IDEA中SSM整合,前端页面jsp] tomcat一开始访问jsp页面就报404错误
  5. 过了这么多年,才发现写的最多的代码竟然是...
  6. 字符变量赋值规则_第四章 变量
  7. 【第三课】ANR和OOM——贪快和贪多的后果(上)
  8. 清除SQLServer2008缓存
  9. 二学位计算机基础试题,计算机基础知识附试题().doc
  10. 91卫图助手免费版发布啦
  11. 医疗器械软件网络安全法规和标准概述(本文末付本文提到的所有标准)
  12. 微信小程序 index.js获取app.js异步请求的动态数据
  13. BZOJ 1924 [Sdoi2010]所驼门王的宝藏 tarjan缩点+拓扑DP
  14. 操作演示 | 如何将示波器波形直接保存到PC端
  15. 机器学习-GridSearchCV scoring 参数设置!
  16. paddlepaddle常见问题解答
  17. uboot2018.7以上版本bison报错
  18. 如果你自己不做出努力的样子,即使人家想拉你,都不知道你的手在哪。
  19. 红外线便携式人体测温仪方案产品说明
  20. 基于深度学习的胃癌IHC图像淋巴细胞自动检测

热门文章

  1. 华为2018实习生软件岗机试题目(2018.04.10)
  2. 并发型服务器响应方式,基于Java NIO 开发高性能并发型服务器程序的研究
  3. 权威发布:社交电商成为下一个风口?
  4. NTT:即将成立以色列子公司
  5. android今日头条图片查看效果,图片查看器ImageViewer:轻松实现微信朋友圈、今日头条、横向列表、纵向列表等图片浏览效果...
  6. Autoencoders
  7. 突破淘宝登录滑块验证反爬,防止识别为Chrome自动控制
  8. Kafka 快速入门(安装)
  9. 小白运用SAI怎样上色?运用SAI上色有技巧嘛?
  10. 兼容和图片整合(浏览器相关及兼容问题)