前言
提示:这是我写这篇文的心理历程
网上有很多命名规则、编程风格,虽然换汤不换药,但是还是有一些差别,而我一个Qt新手,没有师傅教,自己悟性也不高,走这条路,速度上可能很慢,遇到挫折也是难免的,但我知道一定要及时解决!
譬如:
我要开发新项目了,但是从前开发的项目也要好好管理,打开那些项目,函数一看都懂,但是很长时间没接触的话,不知道哪些函数是相关联的,有BUG也不好立马下手修补,需要长时间回顾才知道;
对,这很浪费时间,而有部分原因是因为随意的编码风格使得不好管理,针对这点,自己需要规范编程风格,也就有了这篇文章!
提示:以下是本篇文章正文内容,只为了方便我翻阅、提供大家一种编程风格参考,谢谢阅读|ू・ω・` )
一、头文件模板规则
1. 尽量所有"#include"放在.h文件头部
2. "#include"包含的类顺序
包含头文件的顺序如下:
先 本类需要的Qt库已有的自带的.h文件,
再C语言写的、C++写的、自行下载专用于Qt中的.h文件,
最后自己编写的.h文件。
3. 头文件中 变量、函数 属性定义顺序
在头文件中,定义“变量、函数”的属性有:public、protected、private、public Q_SLOTS、private Q_SLOTS、Q_SIGNALS等,
一般情况下,属性顺序如下(有UI界面的MainWindow为例):
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
protected:
private:
Ui::MainWindow *ui;
public Q_SLOTS:
private Q_SLOTS:
Q_SIGNALS:
};
#endif // MAINWINDOW_H
注意:
必须要有“Q_OBJECT”!
延伸:为什么slots、signals改用Q_SLOTS、Q_SIGNALS宏
以下是新建一个头文件时,自动生成的模型框架:
延伸:为什么将Q_SLOTS放在Q_SIGNALS前面
因为写程序的时候,难免用到getter-setter
函数,这时可以用上Q_PROPERTY()宏,如下代码块所示,你会发现 xxx变量、getXxx()、setXxx()放在一块方便查看检阅!
特殊情况下,属性顺序如下(无UI界面的Scroller 为例):
class Scroller : public QWidget
{
Q_OBJECT
Q_PROPERTY(int currentIndex READ getCurrentIndex WRITE setCurrentIndex)
public:
explicit Scroller(QWidget *parent = 0);
protected:
private:
QStringList listValue; // 值队列
int currentIndex; // 当前索引
private:
void checkPosition(); // 矫正到居中位置
【为了方便getter-setter查阅,public可以放 public Q_SLOTS 前面】
public:
QStringList getListValue() const;
int getCurrentIndex() const;
public Q_SLOTS:
// 设置值队列
void setListValue(const QStringList &listValue);
// 设置当前索引
void setCurrentIndex(int currentIndex);
Q_SIGNALS:
};
你还会发现 红色框内的 三个变量都用了Q_PROPERTY()宏,而蓝色框内的 listValue变量并没有用Q_PROPERTY()宏,可能心存疑惑——难道不是所有getter-setter
函数都要用该宏吗?
答:正常情况下,只要是getter-setter
函数都要用该宏(这样显得规范,也方便查阅),但是并不强制使用,除了这种特殊情况下——用于QML开发时,就必须、强制使用了(如下图所示)!
PS:
涉及信号与槽机制,则一定要加上“Q_OBJECT”宏!
参考文献:
《QT之Qt之Q_PROPERTY宏理解》
延伸:为什么Q_SIGNALS前不用加public等属性,而Q_SLOTS前一定要加
到底是因为什么,直接实践,不就知道了:
看上面两张图,“Q_SLOTS少了作用域属性(public、protected、private)”、“Q_SIGNALS多了private”都会报错!
我点击“问题栏”的异常,系统自动跳到“qobjectdefs.h”文件中98行:
到底表示什么,我也不太清楚,目前网上也没找到答案,等我找到了或伙伴们解答了,我都会在此更新!
参考文献:
《qt 的 signals宏和slots宏》
《Qt 中信号和槽的 C++(public protect private) 的属性》
二、变量函数及类名命名规则
1. 现在大多使用驼峰命名法(Camel-Case)
骆驼式命名法(Camel-Case)又称驼峰式命名法,是电脑程式编写时的一套命名规则(惯例)。正如它的名称CamelCase所表示的那样,是指混合使用大小写字母来构成变量和函数的名字。程序员们为了自己的代码能更容易的在同行之间交流,所以多采取统一的可读性比较好的命名方式。
骆驼式命名法的命名规则可视为一种惯例,并无绝对与强制,为的是增加识别和可读性。
分两种:小驼峰法、大驼峰法(即帕斯卡命名法)
变量、函数名称第一个单词都是小写字母开头,类名名称第一个单词都是大写字母开头;
从第二个单词开始,每个单词大写字母开头。
头文件中定义的代码如下(示例):
变量(一般放在头文件的 private属性 下):
private:
QExcel qExcel或excel;
LookOverPartData lookOver;
QTimer *timer1或*timer;
bool bTemp;
bool bIsClicked;
QString strPortName;
double dMotorCurrVal;【或 double dMotorCurrentValue】
函数(一般放在头文件的 protected属性 下):
protected:
void cleanCells(); // 清空单元格的内容
bool openPort(); // 打开串口,返回bool值
bool eventFilter(QObject *,QEvent *); // 添加过滤器
void setValue(int row, int column, QString value); // 添加根节点值
QString getValue(int row, int column); // 获取单元格的内容
类名:
class CommonFifo : public QObject{};
class QExcel : public QMainWindow{};
class MainWindow : public QMainWindow{};
class ReceiveWindow : public QWidget{};
class LookOverPartialData : public QWidget{};
注意:
①名称尽量不要出现简写,名字再长也要写明白对应变量或函数是代表什么意思!————为的是“可以让别人一眼看懂”,即做到“傻瓜式命名”!
e.g:
QGridLayout *picturesAndVideosLayout
——表示该变量是指多个图片、视频的组合布局(√)
QGridLayout *picAndVidLayout
——表示该变量是指图片视频组合布局(×)
②名称必须出现简写的话,依然遵循“驼峰命名法”!
e.g:
-
class CommonFIFO
——表示该公共类内容是关联FIFO管道的,出现简称FIFO,名称也用FIFO(×)
class CommonFifo
——表示该公共类内容是关联FIFO管道的,出现简称FIFO,名称改为Fifo(√) -
void sendFFmpegInstructions()
——表示该函数是发送FFmpeg指令的方法,出现简称FFmpeg,名称也用FFmpeg(×)
void sendFfmpegInstructions()
——表示该函数是发送FFmpeg指令的方法,出现简称FFmpeg,名称也用Ffmpeg(√)
延伸:信号函数名signal开头、槽函数名slot开头
头文件中定义的代码如下(示例):
槽函数(一般放在头文件的 private Q_SLOTS属性 下):
private Q_SLOTS:
void slotShowLookAt();
void slotClearData();
信号函数(一般放在头文件的 Q_SIGNALS属性 下):
Q_SIGNALS:
void signalShowMain();
void signalSerialPortStatus(bool status);
延伸:初始化类型函数名init开头
头文件中定义的代码如下(示例):
函数(一般放在头文件的 protected属性 下):
protected:
void initForms(); // 首页初始化(初始化界面背景图、控件、布局)
void initLabels(); // 所有Label控件(文本、字体、图片、字体颜色)初始化
void initTimers(); // 定时器变量初始化
void initConnections(); // 建立信号与槽的关系
void initBoolVariates(); // bool变量初始化
延伸:部分bool类型函数名is、has、can开头或able结尾
要根据情况使用,
is-(is开头)
——表示“是不是”,一般用在 adj. 、adj. 可作 v. 或本身就是 v. (过去式) 的前面
has-(has开头)
——表示“有没有”,一般用在 n. 的前面
can-(can开头)
——表示“能不能”,一般用在 v. 的前面
-able(able结尾)
——表示“能不能怎样”,一般用在 v. 的后面,组合后是词典中存在的单词
头文件中定义的代码如下(示例):
函数(一般放在头文件的 protected属性 下):
protected:
bool isClicked(); // 是不是被点了,默认为是
bool isEnabled() const; // 是不是启用了,默认为是【在qwidget.h中】
bool isModal() const; // 是否为模态状态,默认为是【在qwidget.h中】
bool isEmpty() const; // 是否为空,是不是已经空了,默认为是【在qstring.h中】
bool hasCells(); // 是否拥有一个或多个单元格,默认为有
bool hasFocus() const; // 是否拥有输入焦点,默认为有【在qwidget.h中】
bool canWrite(); // 是否能写入数据,默认为能
bool payable(); // 该函数表示应付的,能不能(刷卡、转账)支付,默认为能
延伸:剩余bool类型函数名大多用 驼峰命名法 定义,而 bool类型变量都用b开头,也适用于 驼峰命名法
函数(一般放在头文件的 protected属性 下):
protected:
bool openPort(); // 表示是否打开串口,得到的结果以bool值返回
bool eventFilter(QObject *,QEvent *); // 添加过滤器,添加失败就返回false或QWidget::eventFilter(obj, event)
变量(一般放在头文件的 private属性 下):
private:
bool bIsClicked; // 记录是否被点击的返回值或反馈
bool bIsConnected; // 记录是否已连接的返回值或反馈
bool bHasValues; // 记录是否拥有一个或多个值的返回值或反馈
2.
代码如下(示例):
data = pd.read_csv(
'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv')
print(data.head())
本文参考文献:
《Google C++编程风格指南(一)至(八)》
《Google C++编程风格指南》
《自定义Qt命名规范》
《Qt项目开发规范》
《Qt的编程风格与规范》
该处使用的url网络请求的数据。
三、注释
一般有这几种注释,功能不一,可以方便"查阅"、“双击自动选择部分并拷贝”,请根据自己需要进行使用!
如下代码所示:
//------------------------ 1)不可缩略
void initConnections(); //!< 连接信号与槽
void updateCommonCRC(QString str); //!< 更新指令末端的校验位(帧尾)
bool updateContain(QString str, QString standard,
int minStandard); //!< 更新包含的关系
//------------------------ 2)不可缩略
bool isConnectLight; // 判断是否连接光源,用于判断
int iCommandType; // 命令类型,1 -监听,2 -读取白色、其他通道的配方,3 -写白色和其他通道配方前的计算校验,
// 4 -删除驱动值并关灯,5 -更新输出驱动值,6 -点亮输出驱动值,
// 7 -不删除驱动值并关灯,8 -写白色和其他、剩下2个通道配方前的计算校验,9 -查ID号,
//------------------------ 3)可缩略
/**
* @brief MainWindow::updateChannelData
* 更新通道数据:
* 1 -监听,2 -读取通道配方,3 -写白色和其他通道配方,4 -删除驱动值并关灯,
* 5 -更新输出驱动值,6 -点亮输出驱动值,7 -不删除驱动值并关灯,8 -写白色和其他、剩下2个通道配方前的计算校验,
* 9 -查ID号,
*/
void MainWindow::updateChannelData()
{
QString strTemp = "";
switch (iCommandType) {
case 1:
strTemp = "51 07 0f 04 00 00 00 00 D6";
//------------------------ 4)可缩略
/*
strLightResponseData = "51 07 F0 06 "
+ channelData.strDeviceID + " 4F 4B";
*/
break;
default:
break;
}
}
//------------------------ 5)不可缩略
【一般出现在.pro文件里】
QT += core gui
#QT += axcontainer # 导出为Excel文件,还可以使用ActiveX控件
QT += quickwidgets qml
#QT += xml network # 用到XML及网络相关的类就必须加上这些模块
QT += serialport # 用到串口来连接
CONFIG += c++17 \ # 指定工程配置和编译参数
precompile_header \ #
# Use Precompiled headers (PCH)
PRECOMPILED_HEADER = stable.h
# 指定生成的应用程序放置的目录
#DESTDIR = $$PWD/bin
RESOURCES += \ # 指定需要rcc处理的qrc文件
img.qrc
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。