目录
qt clicked()函数 传递数据
QT读取文件个数:
QT读txt数据并求出行数和列数:
qt读写json:
我的json文件:
读写函数:
换行和不换行的区别就是参数Indented和Compact的区别。
把json写到文件中:
QT信号槽传递不支持的数据该怎么办?
QT信号槽函数的绑定connect函数:
QCheckBox控件的操作:
绑定QCheckBox的信号与槽函数:
QCheckBox设置默认值:
qt clicked()函数 传递数据
当qt按下btn这么能传递数据?
正常情况下当按键按下,qt绑定槽函数是执行槽函数的,但是如果我想按下btn按键槽函数能接收到数据。
看别人的帖子说可以用匿名函数lamda表达式实现。我试了试,还真的可以。所以记录一下。
直接上代码:
重点是connect函数:
connect(ui.btnPictureSavePath, &QPushButton::clicked, _configFileData.get(), [=] () {_configFileData.get()->ChoosePath(cn); });
解释:第一个参数是按键的指针,第二个参数是空间的信号函数,第三个参数是槽指针第四个参数是lamda表达式,也是最关键的一点。需要重点注意一下。
[=] () {_configFileData.get()->ChoosePath(cn); }
_configFileData.get()这个用get函数是因为_configFileData这个指针我用得是智能指针,使用get获取原始指针而已。
这个绑定函数不能用&_configFileData.get()->ChoosePath(cn)这样的,这样是会报错的。
QT读取文件个数:
std::shared_ptr<QDir> dir = std::make_shared<QDir>(path);
QStringList filter;
QFileInfoList fileInfoList = dir->entryInfoList(filter);
int peopleNum = fileInfoList.count() - 2;
需要添加头文件 #include <QDir>
path是QString存储的路径,当然不一定是QString才可以string也是可以的,只要是字符串都可以。
int peopleNum = fileInfoList.count() - 2;为什么要减二,是因为每个文件夹下会有两个默认的文件夹,一个是“.”一个是“..”,意思分别是当前文件夹和上一级文件夹,所有要减2.
fileInfoList这里面存的就是文件夹的名字,第一个和第二个存储的分别是"."和".."。从第三个开始才是文件下有的文件。
QT读txt数据并求出行数和列数:
这个txt存储的是一个矩阵数据,大概长这样的
这么才能快速的读取这个矩阵的行数和列数?
代码:
int row = -1;
int line = -1;
QFile file(path + "/s1_1.txt");
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
{
qDebug() << "Can't open the file!" << endl;
}
QByteArray byte = file.readLine();
QString str(byte);
QStringList strList = str.split(" ");
strList.removeAll("");
line = strList.size();
row = file.size() / file.readLine().size();
QFile file(path + "/s1_1.txt");这行代码就是打开txt文件。
QByteArray byte = file.readLine();这行代码是读取txt一行的数据,注意这个数据并不是我们看到的txt中那样的,这个你可以理解为char数据,是一个字符一个字符的。所以这个数据类型的长度要远远的大于txt中的double数据。
QString str(byte);这句话是吧二进制转换成字符串形式的。
QStringList strList = str.split(" ");这句话是吧字符串以空格分隔,中间是有一个空格的。
strList.removeAll("");这句话是删除多余的空格,因为我这个txt是以tab 分隔的,所以用空格分隔完还有好多空格,所以才有删除所用空格这一句话,如果以单控格分隔就不需要这句话了。
line = strList.size();这句话就是求出一行有多少个double数据,也就是矩阵的列。
行数的求解其实非常的简单,就是读取TXT文件的所有二进制没然后除以一行的二进制数就行了。
row = file.size() / file.readLine().size();也就是这一句话。
qt读写json:
我的json文件:
{
"Data": {
"EEGChannel": 32,
"Frequency": 128,
"FrequencyTime": 60,
"PointNum": 7681,
"path": "F:/code/data/EEG",
"peopleNum": 32,
"testNum": 40
},
"GUI": {
"IsOpenTimer": false,
"TimerPrecision": "",
"style": -1
},
"SQL": {
"IsOpenSQL": false
},
"Text": {
"path": ""
},
"cudaConfig": {
"IsOpen": false
},
"log": {
"KeepTheDate": -1
},
"picture": {
"IsSavePicture": false,
"path": ""
},
"wavelet": {
"depth": -1
}
}
读写函数:
void ConfigFileData::RWConfigFile(bool b)
{
std::shared_ptr<FileOperation> _fileOperation = std::make_shared<FileOperation>();
if (b)// true 读配置文件,false写配置文件
{
QString strConfig = _fileOperation->readJSON(_configFilePath);
QJsonParseError parseJsonErr;
QJsonDocument document = QJsonDocument::fromJson(strConfig.toUtf8(),&parseJsonErr);
if (!(parseJsonErr.error == QJsonParseError::NoError))
{
QMessageBox::about(NULL,"提示","配置文件错误!");
return;
}
QJsonObject jsonObject = document.object();
/****GUI******/
QJsonValue jsonGUIValue = jsonObject.value(QStringLiteral("GUI"));
QJsonObject jsonGUIData = jsonGUIValue.toObject();
_initialized->SetGUIStyle(jsonGUIData["style"].toInt());
_initialized->SetGUIIsOpenTimer(jsonGUIData["IsOpenTimer"].toBool());
_initialized->SetGUITimerPrecision(jsonGUIData["TimerPrecision"].toString());
/******CUDA****/
QJsonValue jsonCUDAConfigValue = jsonObject.value(QStringLiteral("cudaConfig"));
QJsonObject jsonCUDAConfigData = jsonCUDAConfigValue.toObject();
_initialized->SetCudaConfigIsOpen(jsonCUDAConfigData["IsOpen"].toBool());
/********Picture***/
QJsonValue jsonPictureValue = jsonObject.value(QStringLiteral("picture"));
QJsonObject jsonPictureData = jsonPictureValue.toObject();
_initialized->SetPictureIsSavePicture(jsonPictureData["IsSavePicture"].toBool());
_initialized->SetPicturePath(jsonPictureData["path"].toString());
/*******Wavelet**********/
QJsonValue jsonWaveletValue = jsonObject.value(QStringLiteral("wavelet"));
QJsonObject jsonWaveletData = jsonWaveletValue.toObject();
_initialized->SetWaveletDepth(jsonWaveletData["depth"].toInt());
/****Text****/
QJsonValue jsonTextValue = jsonObject.value(QStringLiteral("Text"));
QJsonObject jsonTextData = jsonTextValue.toObject();
_initialized->SetTextPath(jsonTextData["path"].toString());
/*****Log*********/
QJsonValue jsonLogValue = jsonObject.value(QStringLiteral("log"));
QJsonObject jsonLogData = jsonLogValue.toObject();
_initialized->SetLogKeepTheDate(jsonLogData["KeepTheDate"].toInt());
_initialized->SetLogPath(jsonLogData["Path"].toString());
/****SQL*********/
QJsonValue jsonSQLValue = jsonObject.value(QStringLiteral("SQL"));
QJsonObject jsonSQLData = jsonSQLValue.toObject();
_initialized->SetSQLIsOpenSQL(jsonSQLData["IsOpenSQL"].toBool());
/****data*************/
QJsonValue jsonDataValue = jsonObject.value("Data");
QJsonObject jsonDataData = jsonDataValue.toObject();
_initialized->SetDataPath(jsonDataData["path"].toString());
_initialized->SetDataPeopleNum(jsonDataData["peopleNum"].toInt());
_initialized->SetDataTestNum(jsonDataData["testNum"].toInt());
_initialized->SetDataEEGChannel(jsonDataData["EEGChannel"].toInt());
_initialized->SetDataPointNum(jsonDataData["PointNum"].toInt());
_initialized->SetDataFrequency(jsonDataData["Frequency"].toInt());
_initialized->SetDataFrequencyTime(jsonDataData["FrequencyTime"].toInt());
}
else
{
QJsonObject jsonInitialized;
/*****GUI****/
QJsonObject guiJson;
guiJson.insert("style",_initialized->GetGUIStyle());
guiJson.insert("IsOpenTimer",_initialized->GetGUIIsOpenTimer());
guiJson.insert("TimerPrecision",_initialized->GetGUITimerPrecision());
jsonInitialized.insert("GUI",guiJson);
/****CUDA*******/
QJsonObject cudaConfigJson;
cudaConfigJson.insert("IsOpen",_initialized->GetCudaConfigIsOpen());
jsonInitialized.insert("cudaConfig",cudaConfigJson);
/****Picture**********/
QJsonObject pictureJson;
pictureJson.insert("IsSavePicture",_initialized->GetPictureIsSavePicture());
pictureJson.insert("path",_initialized->GetPicturePath());
jsonInitialized.insert("picture", pictureJson);
/*****Wavelet************/
QJsonObject waveletJson;
waveletJson.insert("depth",_initialized->GetWaveletDepth());
jsonInitialized.insert("wavelet",waveletJson);
/*****Text*******/
QJsonObject textJson;
textJson.insert("path",_initialized->GetTextePath());
jsonInitialized.insert("Text",textJson);
/*****Log**********/
QJsonObject logJson;
logJson.insert("KeepTheDate",_initialized->GetLogKeepTheDate());
jsonInitialized.insert("log",logJson);
/*****SQL************/
QJsonObject SQLJson;
SQLJson.insert("IsOpenSQL",_initialized->GetSQLIsOpenSQL());
jsonInitialized.insert("SQL",SQLJson);
/*****data**********/
QJsonObject DataJson;
DataJson.insert("path",_initialized->GetDataPath());
DataJson.insert("peopleNum",_initialized->GetDataPeopleNum());
DataJson.insert("testNum",_initialized->GetDataTestNum());
DataJson.insert("EEGChannel",_initialized->GetDataEEGChannel());
DataJson.insert("PointNum",_initialized->GetDataPointNum());
DataJson.insert("Frequency",_initialized->GetDataFrequency());
DataJson.insert("FrequencyTime",_initialized->GetDataFrequencyTime());
jsonInitialized.insert("Data",DataJson);
/*****JSON************/
QJsonDocument document(jsonInitialized);
QByteArray byteArray = document.toJson(QJsonDocument::Indented);
QString strJson(byteArray);
_fileOperation->write_string_to_file_append(GetConfigFilePath().toStdString(), strJson.toStdString(), std::ios::ate | std::ios::out);
}
}
QByteArray byteArray = document.toJson(QJsonDocument::Indented);
换行和不换行的区别就是参数Indented和Compact的区别。
把json写到文件中:
bool FileOperation::write_string_to_file_append(const std::string& file_string, const std::string str, int model)
{
std::ofstream OsWrite(file_string, model);
OsWrite << str;
OsWrite << std::endl;
OsWrite.close();
return 0;
}
QT信号槽传递不支持的数据该怎么办?
例如信号槽不能传递QVector<int>数据看,只需要在main韩数注册一下:
需要添加头文件 #include <QMetaType>
qRegisterMetaType<QVector<int>>("QVector<int>");
QT信号槽函数子线程传递信号槽函数:
QT里面线程之间传递参数会有一定的特殊性。因此必须加入第五个参数指定,才能够成功的让新线程传递信号给GUI线程。
在connect中第五个参数 添加 Qt::DirectConnection
connect用于连接qt的信号和槽,在qt编程过程中不可或缺。它其实有第五个参数,只是一般使用默认值,在满足某些特殊需求的时候可能需要手动设置。
Qt::AutoConnection:
默认值,使用这个值则连接类型会在信号发送时决定。如果接收者和发送者在同一个线程,则自动使用Qt::DirectConnection类型。如果接收者和发送者不在一个线程,则自动使用Qt::QueuedConnection类型。
Qt::DirectConnection:
槽函数会在信号发送的时候直接被调用,槽函数运行于信号发送者所在线程。效果看上去就像是直接在信号发送位置调用了槽函数。这个在多线程环境下比较危险,可能会造成奔溃。
Qt::QueuedConnection:
槽函数在控制回到接收者所在线程的事件循环时被调用,槽函数运行于信号接收者所在线程。发送信号之后,槽函数不会立刻被调用,等到接收者的当前函数执行完,进入事件循环之后,槽函数才会被调用。多线程环境下一般用这个。
Qt::BlockingQueuedConnection:
槽函数的调用时机与Qt::QueuedConnection一致,不过发送完信号后发送者所在线程会阻塞,直到槽函数运行完。接收者和发送者绝对不能在一个线程,否则程序会死锁。在多线程间需要同步的场合可能需要这个。
Qt::UniqueConnection:
这个flag可以通过按位或(|)与以上四个结合在一起使用。当这个flag设置时,当某个信号和槽已经连接时,再进行重复的连接就会失败。也就是避免了重复连接。
QT信号槽函数的绑定connect函数:
今天遇到一个坑,一个关于信号槽函数绑定的问题。
UI的一个空间QComboBox,我想使用其中的一个信号函数activated来发送数据,然后再自己类写个接受函数。当我按照Qt5推荐的方式写,发现不对后来看了看书说绑定函数使用函数指针的形式信号函数,如果是不同参数同名的函数是不能用函数指针形式的。
所以只能使用老式的绑定函数。demo:
connect(ui.WaveletDepth,SIGNAL(activated(int)), _configFileData.get(), SLOT(SetWaveletDepth(int)));
这个绑定函数,第一个参数是函数指针,第二个参数是一个宏定义,里面是函数名,不需要指定那个类,因为第一个参数已经指定了。第三个参数是接收者的指针,第四个参数也是一个宏定义,里面是一个函数,也不需要指定类。
新式绑定函数:
connect(ui.btnPictureSavePath, &QPushButton::clicked, _configFileData.get(), [=] () {_configFileData.get()->ChoosePath(cn); });
QCheckBox控件的操作:
绑定QCheckBox的信号与槽函数:
cn = CUDAcheckBox;
connect(ui.IsOpenCUDAcheckBox, &QCheckBox::clicked, _configFileData.get(), [=]() {_configFileData->SetUIValue(ui.IsOpenCUDAcheckBox->isChecked(), cn); });
因为空间的clicked函数只有一个函数,所有可以使用函数指针操作。
clicked函数可以读取空间是否按下。
QCheckBox设置默认值:
ui.IsOpenCUDAcheckBox->setChecked(_configFileData->_initialized->GetCudaConfigIsOpen());
setChecked这个函数可以设置空间默认值。