分类 C/C++ 下的文章

Qt: QToolButton颜色选择器


一、概述

项目中需要到了颜色选择器,还不能直接用QColorDialog,必须得有个中间过程,那就只能单独写,上网查了查,没有个正经的dome,自己动手丰衣足食。

二、演示

colorSelecter.gif

三、demo下载

qt_demo.zip (包含了上次的表格相关代码)

四、代码解析

解析先写在注释里,有时间再做解释。

// 封装颜色选择器
class ColorComboBoxAPI ColorComboBox : public QToolButton
{
    Q_OBJECT

public:
    ColorComboBox(QWidget *parent = 0);
    ~ColorComboBox();
    // 设置图标(待处理)
    void setButtonIcon(const QString &imageFile, QColor color);

private:
    // 创建下拉菜单
    QMenu* createColorMenu(const char *slot, const char *slotColorBoard);
    // 创建工具按钮图标(待处理)
    QIcon createColorToolButtonIcon(const QString &imageFile, QColor color);
    // 创建颜色的像素图
    QIcon createColorIcon(QColor color);
    // 根据颜色选择器大小来创建像素图
    QIcon setColorIcon(QColor color);

signals:
    // 颜色改变发的信号
    void sigColorChanged(QColor color);

private slots:
    // 颜色选择
    void OnColorChanged();
    // 显示调色板
    void OnShowColorBoard();
};

五、碰到的问题

显示调色板后的英文问题,不显示中文肯定是不行滴,网上简单搜罗搜罗就找到了办法,但是还是有一点小瑕疵。。中午需要引入qt_zh_CN.qm来做翻译,代码如下,直接加到main里就行。

QTranslator trans;
trans.load("qt_zh_CN.qm","D:\\ProgramFiles\\Qt\\Tools\\QtCreator\\share\\qtcreator\\translations");
app.installTranslator(&trans);

这里的trans.load("qt_zh_CN.qm",qm目录)大家会有疑问,这目录是哪来的,这个是qt自带的,qt的安装目录下就可以找到,拾取的部分还是没有翻译,如果需要的话还是再百度一下吧,别人都是ts文件改了之后转qm,然后再引入。

六、总结

颜色选择器还是挺简单的,不需要太多的代码,其实挺多也都是百度的,就是在这里记录一下。


Qt: 表格控件(多级行列表头、表头单元格合并、右键菜单、内容联动)


概述

所里项目需要写关于Qt表的的东西,主要的东西有合并表头(包括列表头),百度里全都是一些关于QTableWidget的介绍及表格内容的操作啥的(Google里能还能找到几个有用的),关于表头的修改却少之又少,但是还是有两种方法来处理,虽然说是处理不如果说是相关介绍,代码都不知道在哪copy过来的,请问同学们,你们的代码能跑一下么?就算能跑不能分享一下么、、截个代码片段是什么意思。。。不够意思!!!

一、效果展示

  1. 普通合并表头
    屏幕截图 2021-12-25 151245.png
  2. 多级合并表头
    屏幕截图 2021-12-27 095141.png
  3. 右键菜单添加与删除及表格下拉联动
    test.gif

二、demo 下载链接

qt_demo.zip

三、定制表头

重中之重就是HeaderView,麻烦也在它,重写封装好的RTableHeaderView类已放到demo内。

1. 重写HeaderView (概述)

RTableHeaderView继承的QHeaderView, 添加setRowHeight、setColumnWidth、setSpan、setCellBackgroundColor、setCellForegroundColor这几个函数

class MultistageTableHeaderAPI RTableHeaderView : public QHeaderView
{
    Q_OBJECT
public:
    RTableHeaderView(Qt::Orientation orientation,int rows,int columns,QWidget* parent = 0);
    virtual ~RTableHeaderView();

    void setRowHeight(int row, int rowHeight);
    void setColumnWidth(int col, int colWidth);
    void setSpan(int row, int column, int rowSpanCount, int columnSpanCount);
    void setCellBackgroundColor(const QModelIndex& index, const QColor&);
    void setCellForegroundColor(const QModelIndex& index, const QColor&);


protected:
    // override
    virtual void mousePressEvent(QMouseEvent* event) Q_DECL_OVERRIDE;
    virtual QModelIndex indexAt(const QPoint&);
    virtual void paintSection(QPainter* painter, const QRect& rect, int logicalIndex) const Q_DECL_OVERRIDE;
    virtual QSize sectionSizeFromContents(int logicalIndex) const Q_DECL_OVERRIDE;

    // inherent features
    QModelIndex columnSpanIndex(const QModelIndex& currentIndex) const;
    QModelIndex rowSpanIndex(const QModelIndex& currentIndex) const;
    int columnSpanSize(int row, int from, int spanCount) const;
    int rowSpanSize(int column, int from, int spanCount) const;
    int getSectionRange(QModelIndex& index, int* beginSection, int* endSection) const;

protected slots:
    void onSectionResized(int logicalIdx, int oldSize, int newSize);

signals:
    void sectionPressed(int from, int to);
};

2. 定制列表头(概述)

    // 横向表头
    RTableHeaderView* p_header = new RTableHeaderView(Qt::Horizontal, 2, 15, ui->tableWidget);
    QAbstractItemModel* pHeaderModel = p_header->model();
    // 合并表头
    p_header->setSpan(0, 0, 2, 1);
    p_header->setSpan(0, 1, 2, 1);
    p_header->setSpan(0, 2, 1, 13);
    // 设置表头标题内容
    pHeaderModel->setData(pHeaderModel->index(0, 0), QString("Reference"), Qt::DisplayRole);
    pHeaderModel->setData(pHeaderModel->index(0, 1), QString("Action"), Qt::DisplayRole);
    pHeaderModel->setData(pHeaderModel->index(0, 2), QString("Params"), Qt::DisplayRole);
    for (int i = 0; i < 13; i++)
    {
        pHeaderModel->setData(pHeaderModel->index(1, i+2), QString("param_%1").arg(i), Qt::DisplayRole);
    }
    
    // 设置禁止点击
    p_header->setSectionsClickable(false);
    // 设置表头颜色
    p_header->setCellBackgroundColor(pHeaderModel->index(0, 0), 0xcfcfcf);
    p_header->setCellBackgroundColor(pHeaderModel->index(0, 1), 0xcfcfcf);
    p_header->setCellBackgroundColor(pHeaderModel->index(0, 2), 0xcfcfcf);

3. 定制行表头(概述)

    // 纵向表头
    RTableHeaderView* p_vertical = new RTableHeaderView(Qt::Vertical, 6, 2, ui->tableWidget);
    QAbstractItemModel* pVerticalModel = p_vertical->model();
    // 合并表头
    p_vertical->setSpan(0, 0, 2, 2);
    p_vertical->setSpan(2, 0, 2, 1);
    p_vertical->setSpan(4, 0, 2, 1);
    // 设置表头标题内容
    pVerticalModel->setData(pVerticalModel->index(0,0), QString("0"), Qt::DisplayRole);
    pVerticalModel->setData(pVerticalModel->index(2,0), QString("1"), Qt::DisplayRole);
    pVerticalModel->setData(pVerticalModel->index(4,0), QString("2"), Qt::DisplayRole);
    pVerticalModel->setData(pVerticalModel->index(0,1), QString("name"), Qt::DisplayRole);
    pVerticalModel->setData(pVerticalModel->index(1,1), QString("value"), Qt::DisplayRole);
    pVerticalModel->setData(pVerticalModel->index(2,1), QString("name"), Qt::DisplayRole);
    pVerticalModel->setData(pVerticalModel->index(3,1), QString("value"), Qt::DisplayRole);
    pVerticalModel->setData(pVerticalModel->index(4,1), QString("name"), Qt::DisplayRole);
    pVerticalModel->setData(pVerticalModel->index(5,1), QString("value"), Qt::DisplayRole);
    // 设置禁止点击
    p_vertical->setSectionsClickable(false);
    // 设置表头颜色
    p_vertical->setCellBackgroundColor(pHeaderModel->index(0,0), 0xcfcfcf);

四、右键菜单

在table中连接菜单槽函数

connect(ui->tableWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(slotContextMenu(QPoint)));

    QMenu *menu = new QMenu(ui->tableWidget);
    QAction *menu1 = new QAction(QString("添加"));
    QAction *separator = new QAction();
    separator->setSeparator(true);
    QAction *menu2 = new QAction(QString("删除"));
    connect(menu1, SIGNAL(triggered()), this, SLOT(menu_add()));
    connect(menu2, SIGNAL(triggered()), this, SLOT(menu_delete()));
    menu->addAction(menu1);
    menu->addAction(separator);
    menu->addAction(menu2);
    menu->move(QCursor::pos());
    menu->show();

算法(C++): 数值积分(龙贝格积分法)


算法原理

龙贝格(Romberg)求积法是甲酸定积分$T=\int_{a}^{b}f(x)dx$的最常用算法之一。
设$T_{m}(h)$ 步长为h时利用2m-2 阶牛顿-科茨(Newton-Cotes)公式计算得到的结果:$T_{m}(\frac{h}{2})$ 为将步长h减半后用2m-2 阶牛顿-科茨公式计算得到的结果。将他们机型线性组合,便得到步长为h的2m阶牛顿-科茨公式,即:

$$ T_{m+1}(h)=\frac{4^{m}T_{m}(h/2)-T_{m}(h)}{4^{m}-1} $$

其中$T_{1}(h)$为步长为h时的梯形公式计算得到的结果。$T_{1}(h/2)$为步长为h/2时的梯形公式计算得到的结果。
在实际计算时,龙贝格求积法按下表所示的计算格式进行,直到$|T_{m+1}(h)-T_{m}(h)| < \xi$为止。

梯形法则二阶公式四阶公式六阶公式八阶公式···
$T_{1}(h)$
$T_{1}(\frac{h}{2})$$T_{2}(h)$
$T_{1}(\frac{h}{2^{2}})$$T_{2}(\frac{h}{2})$$T_{3}(h)$
$T_{1}(\frac{h}{2^{3}})$$T_{2}(\frac{h}{2^{2}})$$T_{3}(\frac{h}{2})$$T_{4}(h)$
$T_{1}(\frac{h}{2^{4}})$$T_{2}(\frac{h}{2^{3}})$$T_{3}(\frac{h}{2^{2}})$$T_{4}(\frac{h}{2})$$T_{5}(g)$···
::::::

算法实现

double CommonAlgorithm::integral(double (* vFunction)(double x), double a, double b, double eps = 1e-6){
    int m,n,i,k;
    double y[10],h,ep,p,x,s,q;

    // 迭代初值
    h=b-a;
    y[0]=h*(vFunction(a)+vFunction(b))/2.0;
    m=1; 
    n=1; 
    ep=eps+1.0;
    
    // 迭代计算
    while ((ep>=eps)&&(m<=9))
    { 
        p=0.0;
        
        for (i=0;i<=n-1;i++)
        { 
            x=a+(i+0.5)*h;
            p=p+vFunction(x);
        }

        p=(y[0]+h*p)/2.0;
        s=1.0;

        for (k=1;k<=m;k++)
        { 
            s=4.0*s;
            q=(s*p-y[k-1])/(s-1.0);
            y[k-1]=p; p=q;
        }

        ep=fabs(q-y[m-1]);
        m=m+1; 
        y[m-1]=q; 
        n=n+n; 
        h=h/2.0;
    }
    
    return(q);
}

HDF5: C++ 类封装(创建、写入操作)


简介

直接用c的代码写呢太麻烦,用官网的c++用例写呢还乱码,逼得我只能自己写个类来处理了,要不写的东西太多,c的太繁琐,所以自己封装个类方便调用。

hdf5 封装c++ 类

#ifndef _OPEN_HDF5_
#define _OPEN_HDF5_

#include <iostream>
#include <string>
#include <vector>
#include <typeinfo>
#include "h5Cpp.h"

using namespace std;

struct H5TITLE{
    string name;
    string type;
};

/******** ATTR ********/
class CRattr
{
private:
    hid_t hand_id;
public:
    CRattr(hid_t id){
        hand_id = id;
    };
    ~CRattr(){};
    template <class T>
    shared_ptr<CRattr> attr(string key, T value, int len=1){
        hid_t attr_type, attr_space;
        hsize_t attr_dims[1] = { len };
        char* value2 = new char(len);
        if(typeid(T) == typeid(string) || typeid(T) == typeid(char*)){
            attr_type = H5Tcopy(H5T_C_S1);
            H5Tset_size(attr_type, H5T_VARIABLE);
        }else if(typeid(T) == typeid(int)){
            attr_type = H5T_NATIVE_INT;
        }else if(typeid(T) == typeid(double)){
            attr_type = H5T_NATIVE_DOUBLE;
        }else{
            return NULL;
        }
        attr_space = H5Screate_simple(1, attr_dims, NULL);
        hid_t attr = H5Acreate(hand_id, key.c_str(), attr_type, attr_space, H5P_DEFAULT, H5P_DEFAULT);
        if(typeid(T) == typeid(string) || typeid(T) == typeid(char*)){
            H5Awrite(attr, attr_type, value2);
        }else{
            H5Awrite(attr, attr_type, value);
        }
        shared_ptr<CRattr> tmp = make_shared<CRattr>(hand_id);
        return tmp;
    }
};

/******** DATA ********/
class CRdata
{
private:
    hid_t hand_id;
    string dataset_name;
public:
    CRdata(hid_t id, string name){
        hand_id = id;
        dataset_name = name;
    };
    ~CRdata(){};
    template <class T>
    shared_ptr<CRattr> insert(int len, T* wdata, vector<H5TITLE> &title){
        herr_t status;
        hsize_t dims[1] = { len };
        hid_t memtype, space, dset, strtype = H5Tcopy(H5T_C_S1);
        status = H5Tset_size(strtype, H5T_VARIABLE);
        status = H5Tset_cset(strtype, H5T_CSET_UTF8);
        memtype = H5Tcreate(H5T_COMPOUND, sizeof(T));
        int sizet = 0;
        for (int i = 0; i < title.size(); i++)
        {
            if (title.at(i).type == "string" || title.at(i).type == "char") {
                H5Tinsert(memtype, title.at(i).name.c_str(), sizet, strtype);
            } else if (title.at(i).type == "double") {
                H5Tinsert(memtype, title.at(i).name.c_str(), sizet, H5T_NATIVE_DOUBLE);
            } else if (title.at(i).type == "int") {
                H5Tinsert(memtype, title.at(i).name.c_str(), sizet, H5T_NATIVE_INT);
            }
            sizet += sizeof(char*);
        }
        space = H5Screate_simple(1, dims, NULL);
        // 创建数据集
        dset = H5Dcreate(hand_id, dataset_name.c_str(), memtype, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
        // 插入数据
        status = H5Dwrite(dset, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata);

        shared_ptr<CRattr> tmp = make_shared<CRattr>(dset);
        return tmp;
    };
    template <class T>
    shared_ptr<CRattr> insertList(int rows, int cols, T* wdata){
        hid_t space, dset;
        hid_t memtype;
        if (typeid(T) == typeid(double)) {
            memtype = H5T_NATIVE_DOUBLE;
        } else if (typeid(T) == typeid(long double)){
            memtype = H5T_NATIVE_LDOUBLE;
        } else {
            memtype = H5T_NATIVE_INT;
        }

        hsize_t dims[] = { rows, cols };
        space = H5Screate_simple(2, dims, NULL);
        // 创建数据集
        dset = H5Dcreate(hand_id, dataset_name.c_str(), memtype, space, H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
        // 插入数据
        herr_t status = H5Dwrite(dset, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata);
        shared_ptr<CRattr> tmp = make_shared<CRattr>(dset);
        return tmp;
    };
};

/******** GROUP ********/
class CRgroup
{
private:
    hid_t hand_id;
public:
    CRgroup(hid_t id){
        hand_id = id;
    };
    ~CRgroup(){};
    shared_ptr<CRgroup> gopen(string group_name){
        hid_t group_id = H5Gcreate(hand_id, group_name.c_str(), H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
        shared_ptr<CRgroup> tmp = make_shared<CRgroup>(group_id);
        return tmp;
    };
    shared_ptr<CRdata> dataset(string dataset_name){
        shared_ptr<CRdata> tmp = make_shared<CRdata>(hand_id, dataset_name);
        return tmp;
    };
    template <class T>
    shared_ptr<CRattr> attr(string key, T* value, int len = 1){
        shared_ptr<CRattr> tmp = make_shared<CRattr>(hand_id);
        tmp->attr<T>(key, value, len);
        return tmp;
    }
};

/******** FILE ********/
class CRfile
{
private:
    hid_t hand_id;
public:
    CRfile(string file_name){
        hand_id = H5Fcreate(file_name.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
    };
    ~CRfile(){};
    shared_ptr<CRgroup> gopen(string group_name){
        shared_ptr<CRgroup> tmp = make_shared<CRgroup>(hand_id);
        return tmp.gopen(group_name);
    };
    shared_ptr<CRdata> dataset(string dataset_name){
        shared_ptr<CRdata> tmp = make_shared<CRdata>(hand_id, dataset_name);
        return tmp;
    };
    hid_t getHand() {
        return hand_id;
    }
};

#endif

封装的使用示例

    struct mtx{
        double x;
        double y;
        string z;
    };
    struct mt{
        double x;
        double y;
        char* z;
    };

    struct mtx mtt1[5];
    for (int i = 0; i < 5; i++)
    {
        mtt1[i].x = i;
        mtt1[i].y = i;
        mtt1[i].z = "test";
    }

    struct mt mtt2[5];
    for (int i = 0; i < 5; i++)
    {
        mtt2[i].x = mtt1[i].x;
        mtt2[i].y = mtt1[i].y;
        mtt2[i].z = (char*)mtt1[i].z.c_str();
    }

    double wdata[4] = {1,2,3,4};
    Rfile test("test.h5");

    struct mt *wdata2 = new struct mt[5];
    vector<H5TITLE> title = {{"X","double"},{"Y","double"},{"Z","char"}};
    for (int i = 0; i < 5; i++)
    {
        wdata2[i].x = mtt1[i].x;
        wdata2[i].y = mtt1[i].y;
        wdata2[i].z = (char*)mtt1[i].z.c_str();
    }
    
    test.gopen("gtest").gopen("gtest2").dataset("dset").insertList<double>(2,2,wdata);
    int value[1] = {1};
    test.dataset("dtest").insert<mt>(5, wdata2, title).attr<int>("Name", value, 1);
    test.gopen("att").attr<int>("test", value, 1).attr<int>("test2", value, 1);

图示

微信图片编辑_20211129145125.jpg


HDF5: C 用例(创建、写入操作)


介绍

官网很多用例测试,但是全英的优点费劲,这里就将示例总结一下,提高用例的可读性,希望能帮助大家快速上手HDF5.

相关函数及作用

函数名作用
H5Fcreate创建HDF5文件
H5Gcreate创建组

用例代码及说明

#include <iostream>
#include <string>
#include "H5Cpp.h"

#pragma execution_character_set("utf-8")

#define FILE            "h5ex_t_cmpd.h5"
#define DATASET         "DS1"
#define DIM0            10

using namespace std;

struct sensor_r{
    string  location1;
    string  location2;
    string  location3;
    string  location4;
    string  location5;
    string  location6;
    string  location7;
    int     serial_no;
    string  location;
    double  temperature;
    double  pressure;
};

typedef struct {
    char    *location1;
    char    *location2;
    char    *location3;
    char    *location4;
    char    *location5;
    char    *location6;
    char    *location7;
    int     serial_no;
    char    *location;
    double  temperature;
    double  pressure;
} sensor_t;                                 /* Compound type */

int
main (void)
{
    hid_t       file, filetype, memtype, strtype, space, dset;
                                            /* Handles */
    herr_t      status;
    hsize_t     dims[1] = {DIM0};
    int         ndims,
                i;

    sensor_r rdata[DIM0];
    for (int i = 0; i < DIM0; i++)
    {
        rdata[i].location1 = "test";
        rdata[i].location2 = "test中文";
        rdata[i].location3 = "test";
        rdata[i].location4 = "test";
        rdata[i].location5 = "test";
        rdata[i].location6 = "test";
        rdata[i].location7 = "test";
        rdata[i].serial_no = i;
        rdata[i].location = "test123中文";
        rdata[i].temperature = i;
        rdata[i].pressure = 2.0;
    }

    sensor_t * wdata = new sensor_t[DIM0];
    
    for (int i = 0; i < DIM0; i++)
    {
        wdata[i].location1 = (char*)rdata[i].location1.c_str();
        wdata[i].location2 = (char*)rdata[i].location2.c_str();
        wdata[i].location3 = (char*)rdata[i].location3.c_str();
        wdata[i].location4 = (char*)rdata[i].location4.c_str();
        wdata[i].location5 = (char*)rdata[i].location5.c_str();
        wdata[i].location6 = (char*)rdata[i].location6.c_str();
        wdata[i].location7 = (char*)rdata[i].location7.c_str();
        wdata[i].serial_no = i;
        wdata[i].location = (char*)rdata[i].location.c_str();
        wdata[i].temperature = i;
        wdata[i].pressure = 2.0;
        cout << wdata[i].location2 << endl;
    }
    

    /*
     * Create a new file using the default properties.
     */
    file = H5Fcreate (FILE, H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);

    /*
     * Create variable-length string datatype.
     */
    strtype = H5Tcopy (H5T_C_S1);
    status = H5Tset_size (strtype, H5T_VARIABLE);

    /*
     * Create the compound datatype for memory.
     */
    memtype = H5Tcreate (H5T_COMPOUND, sizeof (sensor_t));
    status = H5Tinsert (memtype, "Location1", HOFFSET (sensor_t, location1),strtype);
    status = H5Tinsert (memtype, "Location2", HOFFSET (sensor_t, location2),strtype);
    status = H5Tinsert (memtype, "Location3", HOFFSET (sensor_t, location3),strtype);
    status = H5Tinsert (memtype, "Location4", HOFFSET (sensor_t, location4),strtype);
    status = H5Tinsert (memtype, "Location5", HOFFSET (sensor_t, location5),strtype);
    status = H5Tinsert (memtype, "Location6", HOFFSET (sensor_t, location6),strtype);
    status = H5Tinsert (memtype, "Location7", HOFFSET (sensor_t, location7),strtype);
    status = H5Tinsert (memtype, "Serial number",HOFFSET (sensor_t, serial_no), H5T_NATIVE_INT);
    status = H5Tinsert (memtype, "Location", HOFFSET (sensor_t, location),strtype);
    status = H5Tinsert (memtype, "Temperature (F)", HOFFSET (sensor_t, temperature), H5T_NATIVE_DOUBLE);
    status = H5Tinsert (memtype, "Pressure (inHg)", HOFFSET (sensor_t, pressure), H5T_NATIVE_DOUBLE);

    /*
     * Create dataspace.  Setting maximum size to NULL sets the maximum
     * size to be the current size.
     */
    space = H5Screate_simple (1, dims, NULL);

    /*
     * Create the dataset and write the compound data to it.
     */
    dset = H5Dcreate (file, DATASET, memtype, space, H5P_DEFAULT, H5P_DEFAULT,
                H5P_DEFAULT);
    status = H5Dwrite (dset, memtype, H5S_ALL, H5S_ALL, H5P_DEFAULT, wdata);

    /*
     * Close and release resources.
     */
    status = H5Dclose (dset);
    status = H5Sclose (space);
    status = H5Tclose (memtype);
    status = H5Fclose (file);

    return 0;
}