参考资料地址1:https://pan.baidu.com/s/18K8eI8uNTlqBeBlBBbkYZQ 提取码: gj1e 参考资料地址2:https://share.weiyun.com/2rNgTVDG 密码:naikn9
Qt向开发人员提供了可以轻松设计现代GUI和开发应用程序所必需的多种API。Qt可用于开发C++应用程序,也可使用Qt Quick进行开发。Qt Quick使用QML语言。QML是解释型语言,开发人员即使不熟悉C++知识,也可以用QML设计GUI。
Qt 版本说明 Qt 按照不同的版本发行,分为商业版和开源版 。 Qt 商业版为商业软件提供开发环境,它们提供传统商业软件发行版,并且提供在协议有效期内的免费升级和技术支待服务。而 Qt 开源版是为了开发自由而设计的开放源代码软件,它提供了和商业版本同样的功能,在 GNU 通用公共许可证下,它是免费的。
分析第一个Qt程序 前面章节中,通过在 xxx.ui 文件中拖拽 Label 组件,设计出了一个显示 "Hello,World!" 的窗口。
创建项目 首先,打开 Qt Creator 并创建一个 Qt Widgets Application 项目,创建过程可以参考 《编写第一个Qt程序》一节。需要注意的是,我们要创建一个不带 xxx.ui 文件的项目。
创建项目时,我们在对话框中定义了一个继承自 QMainWindow 的主窗口类,并起名为 MianWindow,该类的定义部分位于 mainwindow.h 头文件中,实现部分位于 mainwindow.cpp 源文件中。
int main( )函数是应用程序的入口。 几乎所有使用Qt的情况下,main()函数只需在将控制转交给Qt库之前执行初始化,然后Qt库通过事件向程序告知用户的行为。 【main.cpp】
#include "dialog.h" //使用哪个类就必须把包含该类的头文件引用过来(*.h文件中包含了相应类的定义)
#include
初始状态下,MainWindow 类由 Q_OBJECT、构造函数和析构函数组成,这里重点介绍一下 Q_OBJECT 和构造函数:
Q_OBJECT:本质是一个已定义好的宏,所有需要“信号和槽”功能的组件都必须将 Q_OBJECT 作为 private 属性成员引入到类中。 带参的构造函数:QWidget 是所有组件的基类,借助 parent 指针,可以为当前窗口指定父窗口。例如图 1 中,QLabel 文本框位于主窗口中,主窗口就是它的父窗口。当父窗口被删除时,所有子窗口也会随之一起删除。当然也可以不指定父窗口,那么当前窗口就会作为一个独立的窗口,不会受到其它窗口的影响。
同理,有的接口必须在用户状态激活的情况才能去操作,不然只能看看,这也是很多网站的惯用手段。增加限制,促进用户主动去填写资料。 com.imooc.api.interceptors.UserTokenInterceptor。 /**
用户激活状态检查拦截器
发文章,修改文章等
发评论,查看评论等
查看我的粉丝等,这些媒体中心的功能必须用户激活后,才能进行,
否则提示用户前往[账号设置]去修改信息
/ public class UserActiveInterceptor implements HandlerInterceptor {
@Autowired private RedisOperator redis;
public static final String REDIS_USER_INFO = "redis_user_info";
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String userId = request.getHeader("headerUserId"); // 1. 偷懒,可以从userController中拷贝过来 String userJson = redis.get(REDIS_USER_INFO + ":" + userId); AppUser user = null; if (StringUtils.isNotBlank(userJson)) { user = JsonUtils.jsonToPojo(userJson, AppUser.class); } else { GraceException.display(ResponseStatusEnum.UN_LOGIN); return false; } // 如果不是激活状态则不能执行后续操作 if (user.getActiveStatus() == null || user.getActiveStatus() != UserStatus.ACTIVE.type) { GraceException.display(ResponseStatusEnum.USER_INACTIVE_ERROR); return false; } return true;
} }
监控所有service,针对不同service的执行时间进行日志打印 com.imooc.api.aspect.ServiceLogAspect @Aspect @Component public class ServiceLogAspect {
public static final Logger log =
LoggerFactory.getLogger(ServiceLogAspect.class);
/**
* AOP通知:
* 1. 前置通知:在方法调用之前执行
* 2. 后置通知:在方法正常调用之后执行
* 3. 环绕通知:在方法调用之前和之后,都分别可以执行的通知
* 4. 异常通知:如果在方法调用过程中发生异常,则通知
* 5. 最终通知:在方法调用之后执行
*/
/**
* 切面表达式:
* execution 代表所要执行的表达式主体
* 第一处 * 代表方法返回类型 *代表所有类型
* 第二处 包名代表aop监控的类所在的包
* 第三处 .*. 代表匹配某一个包,因为我们命名的包都是有一定的规则规范的
* 第四处 .. 代表该包以及其子包下的所有类方法
* 第五处 * 代表类名,*代表所有类
* 第六处 *(..) *代表类中的方法名,(..)表示方法中的任何参数
*
* @param joinPoint
* @return
* @throws Throwable
*/
@Around("execution(* com.imooc.*.service.impl..*.*(..))")
public Object recordTimeLog(ProceedingJoinPoint joinPoint) throws Throwable {
log.info("====== 开始执行 {}.{} ======",
joinPoint.getTarget().getClass(),
joinPoint.getSignature().getName());
// 记录开始时间
long begin = System.currentTimeMillis();
// 执行目标 service
Object result = joinPoint.proceed();
// 记录结束时间
long end = System.currentTimeMillis();
long takeTime = end - begin;
if (takeTime > 3000) {
log.error("====== 执行结束,耗时:{} 毫秒 ======", takeTime);
} else if (takeTime > 2000) {
log.warn("====== 执行结束,耗时:{} 毫秒 ======", takeTime);
} else {
log.info("====== 执行结束,耗时:{} 毫秒 ======", takeTime);
}
return result;
}
}