当前位置: 首页 > article >正文

Qt5中使用EPICS通道访问读写EPICS PV

1、用Qt Creator创建一个Qt Widget项目ChannelAccess,并且在其生成的ChannelAccess.pro中添加以下行:

#
# Project created by QtCreator 2023-06-27T02:06:24
#
#-------------------------------------------------

QT       += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = ChannelAccess
TEMPLATE = app


SOURCES += main.cpp\
        mainwindow.cpp \
    pvchannels.cpp

HEADERS  += mainwindow.h \
    pvchannels.h

FORMS    += mainwindow.ui

# 以下是添加了EPICS base通道访问库的头文件的路径以及库文件的位置
INCLUDEPATH += /usr/local/EPICS/base/include
INCLUDEPATH += /usr/local/EPICS/base/include/os/Linux
INCLUDEPATH += /usr/local/EPICS/base/include/compiler/gcc
LIBS += /usr/local/EPICS/base/lib/linux-x86_64/libca.so.4.13.5
LIBS += /usr/local/EPICS/base/lib/linux-x86_64/libCom.so.3.17.6

2、mainwindow.ui的设计如下:

3、添加一个名为pvchannels的类,其在Headers和Sources下分别生成了一个名为pvchannels.h和pvchannels.cpp文件:

编辑以上两个文件:

1)pvchannels.h:

#ifndef PVCHANNELS_H
#define PVCHANNELS_H
#include "cadef.h"
#include <QString>
#include <QDebug>

class pvchannels
{
public:
    pvchannels(const char * pvname);
    ~pvchannels();

    void pv_init();

    void Display();
    double getValue();
    void updateValue();
    void writeValue(double value);

private:
    QString     pvname_;
    chid        mychid_;
    double      data_;
    unsigned    elementcount_;
    double *    pdoubles_;
};

#endif // PVCHANNELS_H

2)pvchannels.cpp:

#include "pvchannels.h"

pvchannels::pvchannels(const char *pvname)
{
    this->pvname_ = pvname;
    this->pdoubles_ = NULL;
}

pvchannels::~pvchannels()
{
    if (this->pdoubles_ != NULL){
        free(this->pdoubles_);
    }
    this->pdoubles_ = NULL;

    ca_clear_channel(this->mychid_);
//    ca_context_destroy();
}

void pvchannels::pv_init()
{
    SEVCHK(ca_context_create(ca_disable_preemptive_callback),"ca_context_create");
    SEVCHK(ca_create_channel(this->pvname_.toLatin1().data(), NULL, NULL, 10 , &this->mychid_), "ca_create_channel failure");
    SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
    SEVCHK(ca_get(DBR_DOUBLE, this->mychid_, (void *)&data_), "ca_get failure");
    SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");

    this->elementcount_ = ca_element_count(mychid_);

    if (this->elementcount_ > 1){
        this->pdoubles_ = (double *) malloc(sizeof(double) * this->elementcount_);

        SEVCHK(ca_array_get(DBR_DOUBLE, this->elementcount_, this->mychid_, (void *)pdoubles_), "ca_array_get failed");
        SEVCHK(ca_pend_io(5.0), "ca_pend_io failed");
    }
}

void pvchannels::Display()
{
    qDebug() << "Data:" << this->data_;
    qDebug() << "Count:" << this->elementcount_;
}

void pvchannels::updateValue()
{
    if (this->elementcount_ > 1){
        SEVCHK(ca_array_get(DBR_DOUBLE, this->elementcount_, this->mychid_, (void *)pdoubles_), "ca_array_get failed");
    }
    else{
         SEVCHK(ca_get(DBR_DOUBLE, this->mychid_, (void *)&data_), "ca_get failure");
    }
    SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
}

void pvchannels::writeValue(double value)
{
    this->data_ = value;
    SEVCHK(ca_put(DBR_DOUBLE, this->mychid_, (void *)&data_), "ca_put failure");
    SEVCHK(ca_pend_io(5.0), "ca_pend_io failure");
}

double pvchannels::getValue()
{
    return data_;
}

3) 编辑mainwindow..h头文件:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <vector>
#include <QMainWindow>
#include <QLineEdit>
#include <QLabel>
#include "pvchannels.h"

using namespace std;

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();


private slots:
    void on_BtnGetPVs_clicked();

    void on_MonitorButton_clicked();

    void on_BtnUpdatePVs_clicked();

    void on_BtnWritePVs_clicked();

    void on_BtnDisconnectPVs_clicked();

private:
    Ui::MainWindow *ui;
    vector<QLineEdit *> vec;
    vector<QLabel *>veclabel;
    vector<pvchannels *> vecpvs;
    vector<QLineEdit *> vecwrite;
    pvchannels * pv_monitor;
    bool isConnected;
};

#endif // MAINWINDOW_H

3) 编辑mainwindow..cpp头文件:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <vector>
#include "pvchannels.h"
#include <QMessageBox>
#include <QDoubleValidator>
#include <QDebug>
//#include <QtChart>

using namespace std;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ui->leWritePV1->setValidator(new QDoubleValidator());
    ui->leWritePV2->setValidator(new QDoubleValidator());
    ui->leWritePV3->setValidator(new QDoubleValidator());
    ui->leWritePV4->setValidator(new QDoubleValidator());
    vecwrite.push_back(ui->leWritePV1);
    vecwrite.push_back(ui->leWritePV2);
    vecwrite.push_back(ui->leWritePV3);
    vecwrite.push_back(ui->leWritePV4);
    vec.push_back(ui->lineEdit_PV1);
    vec.push_back(ui->lineEdit_PV2);
    vec.push_back(ui->lineEdit_PV3);
    vec.push_back(ui->lineEdit_PV4);
    veclabel.push_back(ui->label_v1);
    veclabel.push_back(ui->label_v2);
    veclabel.push_back(ui->label_v3);
    veclabel.push_back(ui->label_v4);

    pv_monitor = NULL;
    isConnected = false;

}

MainWindow::~MainWindow()
{
    if (pv_monitor != NULL){
        delete pv_monitor;
        pv_monitor = NULL;
    }

    vector<pvchannels *>::iterator itpvs = vecpvs.begin();

    for (; itpvs != vecpvs.end(); ++itpvs){
        pvchannels * ppv = * itpvs;
        delete ppv;
    }
    delete ui;
}



void MainWindow::on_BtnGetPVs_clicked()
{
    vector<QLineEdit *>::iterator it;
    vector<QLabel *>::iterator itlabel;
    vector<QLineEdit *>::iterator itwrite;

    vecpvs.clear();
    if (isConnected ==  false){
        isConnected = true;

        for (it = vec.begin(), itlabel = veclabel.begin(), itwrite = vecwrite.begin();  \
             it != vec.end()&& itlabel != veclabel.end() && itwrite != vecwrite.end(); \
             ++it, ++itlabel, ++itwrite){
            QLineEdit * pedit = * it;

            QString pvname = pedit->text();

            qDebug() << "pvname: " << pvname;
            pvchannels * ppv = new pvchannels(pvname.toUtf8().data());
            ppv->pv_init();

            (*itlabel)->setText(QString::number(ppv->getValue()));
            (*itwrite)->setText(QString::number(ppv->getValue()));
            vecpvs.push_back(ppv);
        }

        ui->BtnUpdatePVs->setEnabled(true);
        ui->BtnWritePVs->setEnabled(true);
        ui->BtnGetPVs->setEnabled(false);
        ui->BtnDisconnectPVs->setEnabled(true);
   }


}

void MainWindow::on_MonitorButton_clicked()
{
    QString pvname = ui->lineEditMonitor->text();
    if (pv_monitor == NULL){
        pv_monitor = new pvchannels(pvname.toLatin1().data());
        pv_monitor->pv_init();
    }
    else{
        pv_monitor->updateValue();
    }

    QMessageBox::information(this, "PV Monitor", QString::number(pv_monitor->getValue()));
}

void MainWindow::on_BtnUpdatePVs_clicked()
{
    vector<pvchannels *>::iterator it;
    vector<QLabel *>::iterator itlabel;
    vector<QLineEdit *>::iterator itwrite;


    for (it = vecpvs.begin(), itlabel = veclabel.begin() , itwrite = vecwrite.begin();  \
         it != vecpvs.end() && itlabel != veclabel.end() && itwrite != vecwrite.end(); \
         ++it, ++itlabel, ++itwrite){
        pvchannels * ppv = *(it);
        ppv->updateValue();
        (* itlabel)->setText(QString::number(ppv->getValue()));
        (* itwrite)->setText(QString::number(ppv->getValue()));
    }
}

void MainWindow::on_BtnWritePVs_clicked()
{
    vector<pvchannels *>::iterator itpvs;
    vector<QLineEdit *>::iterator  it;

    for (it = vecwrite.begin(), itpvs = vecpvs.begin(); it != vecwrite.end() && itpvs != vecpvs.end(); ++it, ++itpvs){
        QString str = (*it)->text();
        double value = str.toDouble();
//        qDebug() << value;
        (* itpvs)->writeValue(value);

    }

    this->on_BtnUpdatePVs_clicked();
}

void MainWindow::on_BtnDisconnectPVs_clicked()
{
    if (isConnected == true){
        isConnected = false;

        ui->BtnDisconnectPVs->setEnabled(false);
        ui->BtnGetPVs->setEnabled(true);
        ui->BtnUpdatePVs->setEnabled(false);
        ui->BtnWritePVs->setEnabled(false);

        vector<pvchannels *>::iterator itpvs = vecpvs.begin();

        for (; itpvs != vecpvs.end(); ++itpvs){
            pvchannels * ppv = * itpvs;
            delete ppv;
        }

        QMessageBox::information(this , "Disconnect PV", "Diconntect PVs");
    }
}

5) 最后编辑main.cpp源文件:

#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
#include <QLoggingCategory>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
     QLoggingCategory::defaultCategory()->setEnabled(QtDebugMsg, true);
    MainWindow w;
    w.show();


    return a.exec();
}

6)选择菜单项Build->Build Project “ChannelAccess”,编译项目。等编译结束,选择Run,运行这个项目。

在PV列中输入想要连接的EPICS PV,点击Connnect PVs,就可以连接指定的PV,并且回读PV的当前值。

如果想要读取当前的PV值,点击Update PVs,如果想要更改PV,则在右侧Write Value列中写入想要更新的值,然后点击WritePVs,完成PV的写操作。 


http://www.kler.cn/a/422160.html

相关文章:

  • 46 基于单片机的烧水壶系统设计
  • 浅谈——Linux命令入门之前奏
  • 故障诊断 | Transformer-LSTM组合模型的故障诊断(Matlab)
  • Linux下,用ufw实现端口关闭、流量控制(二)
  • Ollama是什么
  • Python办公——openpyxl处理Excel每个sheet每行 修改为软雅黑9号剧中+边框线
  • Qt几何数据类型:QLine类型详解(基础向)
  • 时序图学习
  • 1203论文速读
  • llvm源码编译
  • 基于Java Springboot旅游攻略APP且微信小程序
  • 6.824/6.5840(2024)环境配置wsl2+vscode
  • 使用Apache HttpClient发起一个POST HTTP请求
  • 【Android 腾讯地图】腾讯地图开发记录 ① ( 地图基础显示 | 创建应用和申请key | 配置远程依赖库 | 配置腾讯地图 Key | 同意隐私协议 | 布局设置 | 覆盖自定义地图图片 )
  • burp2
  • DeviceIoControl超时后如何处理
  • 【Spring】接口版本控制最佳实现
  • Vue3 父子组件传值
  • ESLint 规则入门:如何配置重要性及选项(2)
  • 【数据分析】如何根据数据选择图表类型
  • 【Android】组件化嘻嘻嘻gradle耶耶耶
  • 下载 M3U8 格式的视频
  • c++ mfc调用UpdateData(TRUE)时,发生异常
  • ElasticSearch easy-es 聚合函数 group by 混合写法求Top N 词云 分词
  • k8s,声明式API对象理解
  • 基于Java Springboot广西文化传承微信小程序