24章全-Qt 全流程实战企业级项目 - 云对象存储浏览器

双寿
• 阅读 325

参考资料地址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 //每个使用[Qt图形化应用程序]中都必须使用一个QApplication对象 //QApplication管理各种各样的图形化应用程序的广泛资源、基本设置、控制流及事件处理等 int main(int argc, char *argv[]) //这里是应用程序的入口。几乎所有使用Qt的情况下,main()函数只需在将控制转交给Qt库之前执行初始化,然后Qt库通过事件向程序告知用户的行为。 //所有Qt程序必须有且只有一个main()函数。argc是命令行变量的数量,argv是命令行变量的数组。 { QApplication a(argc, argv); // a是创建的QApplication类的对象,用来处理命令行变量。所有被Qt识别的命令行参数都将从argv中移去,argc也因此减少 Dialog w; //创建对话框Dialog类的对象(包含该类头文件) w.show(); //窗口部件可见 return a.exec(); //main()函数将控制权交给Qt,Qt完成事件处理工作,当应用程序退出的时候,exec()函数的值就会返回。 //exec()函数中,Qt接收并处理用户和系统的事件,并且将他们传递给适当的窗口部件。 }

初始状态下,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;
}

}

点赞
收藏
评论区
推荐文章
荀勗 荀勗
5个月前
首个基于Transformer的分割检测+视觉大模型视频课程(附源码+课件)
参考资料地址1:https://pan.baidu.com/s/14g2VTg8JeeZ0pDey7xwGg提取码:2bmp参考资料地址2:https://share.weiyun.com/tnVNHGMD密码:3fj7iy众所周知,视觉系统对于理解和推理
荀勗 荀勗
5个月前
[24章]Qt 全流程实战企业级项目 - 云对象存储浏览器
下载地址1:https://pan.baidu.com/s/180fnOsA0EwGXcLb3icyw提取码:laa9下载地址2:https://pan.baidu.com/s/1adwzeyb1CKJrGiu2zpolQ提取码:a5p2Qt开发浏览器全流
荀勗 荀勗
5个月前
高性能多级网关与多级缓存架构落地实战(完结+附电子书)
参考资料地址1:https://pan.baidu.com/s/12w0TT26aywnoIcogPg8Uw提取码:uzf4参考资料地址2:https://share.weiyun.com/SNltUNLW密码:zi3dc7什么是网关?网关(Gateway
荀勗 荀勗
5个月前
[新版16章+电子书]SpringBoot+Vue3 项目实战,打造企业级在线办公系统
参考资料地址1:https://pan.baidu.com/s/1KmJP0OPD5P6iHlT7G1MIw提取码:4wyi参考资料地址2:https://share.weiyun.com/jVSDdcBU密码:cruqf9一个完整的在线办公系统具备哪些功
吉太 吉太
5个月前
[2023新版16章]SpringBoot+Vue3 项目实战,打造企业级在线办公系统
参考资料地址1:https://pan.baidu.com/s/1ZJGS0SA9pIUr76VUXioNSg提取码:95bd参考资料地址2:https://share.weiyun.com/jVSDdcBU密码:cruqf9SpringBootVue3
赵嬷嬷 赵嬷嬷
4个月前
[完结10章]Vue3+Pinia+Vite+TS 还原高性能外卖APP项目
参考资料地址1:https://pan.baidu.com/s/1u0uNBMkOA2NRk3N6myb4Zg提取码:tnlt参考资料地址2:https://share.weiyun.com/Wjw3QpeQ密码:gxrfcwVue3带来的改变,除了其自身
双寿 双寿
4个月前
大模型之最火Agent实战(打造你代理)教程
参考资料地址1:https://pan.baidu.com/s/1ymxhyeFjJX8DY3VeYJohg提取码:7k1q参考资料地址2:https://share.weiyun.com/olW8Mzf0密码:6bag56代理(Agent)指能自主感知环
双寿 双寿
4个月前
慕课甄选-2024年Flutter零基础极速入门到进阶实战[16章]
参考资料地址1:https://pan.baidu.com/s/1j35W30a7JQAGTV2rYgxRNA提取码:5o3h参考资料地址2:https://pan.baidu.com/s/1Iwj10AL7jdum19WQz1jdA提取码:0n8xFlu
双寿 双寿
3个月前
C++从0实现百万并发Reactor服务器[完结13章]
参考资料地址1:https://pan.baidu.com/s/19N2Dw56c4EMeu3s7hIaTQ提取码:sjym参考资料地址2:https://share.weiyun.com/yAMzj8N9密码:viangdReactor模式也叫做反应器设
吉太 吉太
3个月前
C++从0实现百万并发Reactor服务器[完结13章]
参考资料地址1:https://pan.baidu.com/s/10hWsc5kaC1uQGQpMsZsw提取码:xn6a参考资料地址2:https://share.weiyun.com/yAMzj8N9密码:viangd一、reactor是什么?怎么理解