文档管理中心
|

HarmonyOS 6

HarmonyOS 5

HarmonyOS PC中Qt项目主窗口显示登录模态窗示例

场景介绍

HarmonyOS PC中Qt项目主窗口显示登录模态窗是Qt项目高频使用场景之一,例如实现主页面与登录对话框同时显示,登录后即可显示指定内容,若未登录则以游客模式访问;或者实现模态窗成功登录后才能显示主窗口功能。
本示例基于Qt框架使用QDialog创建登录对话框,并调用exec函数以模态方式显示弹窗,从而显示登录模态窗。

效果预览

  • 场景一:主窗口与登录模态窗同时显示。

    cke_1262.png

  • 场景二:模态窗成功登录后显示主窗口。

实现思路

开源版与商业版Qt项目中,cpp目录下的代码实现思路一致。本示例基于开源版Qt实现,具体内容如下:

  • 场景一:主窗口与登录模态窗同时显示。

    1. 编写qrc资源文件,并手动创建文件夹后放入图片文件。在img文件夹中放入未登录时的icn.png头像图片及visitor.png图片,已登录时的user.png头像图片及login.png图片。

      cke_78211.png

    2. 在CMakeLists.txt文件中,加入所需的cpp文件、头文件及qrc资源文件,部分代码如下:

      收起
      自动换行
      深色代码主题
      复制
      add_library(qtmodule SHARED main.cpp mainwindow.cpp mainwindow.h logindialog.cpp logindialog.cpp image.qrc)
    3. 为实现更新登录状态,在mainwindow.cpp中定义了UpdateLoginStatus函数。其核心是根据状态,使用QPixmap从qrc资源加载对应图片并更新显示。代码如下:

      收起
      自动换行
      深色代码主题
      复制
      void MainWindow::UpdateLoginStatus(bool isLogin)
      {
          m_isLogin = isLogin;
          if (isLogin) {
              setWindowTitle("应用主界面 - 已登录");
              m_avatarLabel->setPixmap(QPixmap(":/img/user.png"));
              m_nameLabel->setText("Test用户");
              m_nameLabel->setStyleSheet("font-size: 18px; font-weight: bold; color: #333; margin-top: 8px;");
              updateRightImage(":/img/login.png");
          } else {
              setWindowTitle("应用主界面");
              m_avatarLabel->setPixmap(QPixmap(":/img/icn.png"));
              m_nameLabel->setText("点击登录");
              m_nameLabel->setStyleSheet("font-size: 18px; font-weight: bold; color: #333; margin-top: 8px;"); 
              updateRightImage(":/img/visitor.png");
          }
      }
    4. QDialog中调用setModal函数设置登录窗口是否为模态窗口,logindialog.cpp文件中部分代码如下:

      收起
      自动换行
      深色代码主题
      复制
      setModal(true);
    5. 调用exec函数以模态方式显示弹窗,将阻塞后续代码执行直到关闭弹窗,logindialog.cpp文件中自定义showLogin函数代码如下:

      收起
      自动换行
      深色代码主题
      复制
      bool LoginDialog::showLogin(QWidget *parent)
      {
          LoginDialog dlg(parent);
          dlg.move(parent->geometry().center() - dlg.rect().center());
          bool success = (dlg.exec() == QDialog::Accepted) && dlg.m_isLoginSuccess;
          return success;
      }
    6. main.cpp文件中创建了两个窗口:作为父窗口的主窗口,以及作为子窗口的登录模态窗。核心代码如下:

      收起
      自动换行
      深色代码主题
      复制
      MainWindow mainWin;
      mainWin.show();
      
      bool firstLogin = LoginDialog::showLogin(&mainWin);
      mainWin.UpdateLoginStatus(firstLogin);
  • 场景二:模态窗成功登录后显示主窗口。
  1. 编写qrc资源文件,并手动创建文件夹后放入图片文件。在img文件夹中放入已登录时的user.png头像图片及login.png图片。

    cke_103937.png

  2. 在CMakeLists.txt文件中,加入所需的cpp文件、头文件及qrc资源文件,部分代码如下:
    收起
    自动换行
    深色代码主题
    复制
    add_library(qtmodule SHARED main.cpp clickableuserwidget.cpp clickableuserwidget.h logindialog.h logindialog.cpp mainwindow.cpp mainwindow.h image.qrc)
  3. 在mainwindow.cpp文件中,使用QSystemTrayIcon创建托盘对象,并为其配置包含多个项目的右键菜单。使用QAction创建菜单项,并通过信号槽机制与对应函数连接,代码如下:
    收起
    自动换行
    深色代码主题
    复制
    void MainWindow::InitTrayIcon()
    {
        trayIcon = new QSystemTrayIcon(this);
        QIcon defaultIcon = qApp->style()->standardIcon(QStyle::SP_ComputerIcon);
        trayIcon->setIcon(defaultIcon);
        qDebug() << "托盘图标创建完成,是否可见:" << trayIcon->isVisible();
        qDebug() << "系统托盘是否可用:" << QSystemTrayIcon::isSystemTrayAvailable();
    
        trayMenu = new QMenu(this);
        
        showWindowAction = new QAction("显示主窗口", trayMenu);
        hideWindowAction = new QAction("隐藏主窗口", trayMenu);
        exitAction = new QAction("退出程序", trayMenu);
    
        trayMenu->addAction(showWindowAction);
        trayMenu->addAction(hideWindowAction);
        trayMenu->addAction(exitAction);
    
        trayIcon->setContextMenu(trayMenu);
    
        connect(showWindowAction, &QAction::triggered, this, &MainWindow::OnShowWindow);
        connect(hideWindowAction, &QAction::triggered, this, &MainWindow::OnHideWindow);
        connect(exitAction, &QAction::triggered, this, &MainWindow::OnExit);
        connect(trayIcon, &QSystemTrayIcon::activated, this, &MainWindow::OnTrayActivated);
        connect(trayIcon, &QSystemTrayIcon::messageClicked, this, &MainWindow::OnShowWindow);
    
        trayIcon->show();
    }
  4. 在main.cpp文件中,调用setQuitOnLastWindowClosed函数设置关闭最后一个窗口时不退出程序,代码如下:
    收起
    自动换行
    深色代码主题
    复制
    QApplication a(argc, argv);
    a.setQuitOnLastWindowClosed(false);
  5. main.cpp文件中使用QDialog创建登录对话框,并通过调用exec函数将其以模态方式显示。点击“确认”按钮后关闭登录窗口并显示主窗口,代码如下:
    收起
    自动换行
    深色代码主题
    复制
    MainWindow w;
    LoginDialog loginDlg;
    qDebug() << "登录对话框启动";
    int loginResult = loginDlg.exec();
    if (loginResult == QDialog::Accepted) {
        qDebug() << "登录成功,调用显示主窗口";
        w.OnShowWindow();
    } else {
        qDebug() << "登录取消/失败,退出程序";
        return 0;
    }

说明

使用该示例需要完成下面两个操作:

  1. libs\arm64-v8a下的libplugins_platforms_qopenharmony.so文件替换为本地Qt安装路径\plugins\platforms目录下的libplugins_platforms_qopenharmony.so,以及将libplugins_imageformats_qjpeg.so文件替换为本地Qt安装路径\plugins\imageformats目录下的libplugins_imageformats_qjpeg.so

  2. 将开源版Qt安装路径配置到QT_PREFIX中,可以选择下面两个方案中的一个:

    • 修改entry\src\main\cpp\CMakeLists.txt文件,将QT_PREFIX变量的值从"D:\\arkTSProject\\QtSdkOpen\\ohos17_arm64-v8a_release"更新为本地Qt编译输出目录路径:
      收起
      自动换行
      深色代码主题
      复制
      # 检查环境变量是否存在
      if(DEFINED ENV{WORKSPACE})
         set(QT_PREFIX $ENV{WORKSPACE}/code/SDK/Qt/QtOpenSDK)
         message(STATUS "get QT_PREFIX PATH: ${QT_PREFIX}")
      else()
         set(QT_PREFIX "D:\\arkTSProject\\QtSdkOpen\\ohos17_arm64-v8a_release")
         message(STATUS "WORKSPACE not defined, using default path: ${QT_PREFIX}")
      endif()
    • 或者删除entry\src\main\cpp\CMakeLists.txt中的QT_PREFIX定义,在entry\build-profile.json5中设置QT_PREFIX
      收起
      自动换行
      深色代码主题
      复制
      "buildOption": {
         "externalNativeOptions": {
            "path": "./src/main/cpp/CMakeLists.txt",
            "arguments": "-DQT_PREFIX=D:\\arkTSProject\\QtSdkOpen\\ohos17_arm64-v8a_release",
            "cppFlags": "",
            "abiFilters": ["arm64-v8a"]
         }
      },

【常见FAQ】
Q:项目运行后,qrc资源文件中的图片为什么无法显示?
A:在libs\arm64-v8a目录中放入本地Qt安装路径\plugins\imageformats目录下的libplugins_imageformats_qjpeg.so即可。

约束与限制

  • 本示例支持API Version 20 Release及以上版本。
  • 本示例支持HarmonyOS 6.0.0 Release SDK及以上版本。
  • 本示例需要使用DevEco Studio 6.0.0 Release及以上版本进行编译运行。

工程目录

  • 场景一基于开源版Qt工程的ParallelLaunch目录。
    收起
    自动换行
    深色代码主题
    复制
    ├─entry
    │  ├─libs/arm64-v8a
    │  │  ├─libplugins_imageformats_qjpeg.so  
    │  │  └─libplugins_platforms_qopenharmony.so    // Qt安装目录'plugins\platforms'HarmonyOS平台插件so
    │  └─src
    │      ├─main
    │      │  ├─cpp
    │      │  │  ├─img                              // 图片文件夹
    │      │  │  │  ├─icn.png                       // 未登录头像图片
    │      │  │  │  ├─login.png                     // 已登录显示图片
    │      │  │  │  ├─user.png                      // 登录头像图片
    │      │  │  │  └─visitor.png                   // 未登录显示图片
    │      │  │  ├─CMakeLists.txt                   // Qt项目CMakeList文件
    │      │  │  ├─image.qrc                        // Qt资源文件
    │      │  │  ├─logindialog.cpp                  // 登录弹窗cpp文件
    │      │  │  ├─logindialog.h                    // 登录弹窗头文件
    │      │  │  ├─main.cpp                         // Qt的主入口
    │      │  │  ├─mainwindow.cpp                   // 主窗口cpp文件
    │      │  │  └─mainwindow.h                     // 主窗口头文件
    │      │  ├─ets
    │      │  │  ├─abilitystage
    │      │  │  │  └─MyAbilityStage.ets
    │      │  │  ├─entryability
    │      │  │  │  └─EntryAbility.ets              // 应用入口
    │      │  │  └─pages
    │      │  │     └─Index.ets                     // 主页面实现
    │      │  ├─resources                           // 应用资源目录
    │      │  └─module.json5                        // 模块级核心配置文件
    │      ├─build-profile.json5                    // 工程结构/构建/定制化配置信息
    │      └─oh-package.json5                       // 描述全局配置
    └─hvigor                                        // 构建环境配置
  • 场景二基于开源版Qt工程的LoginFirst目录。
    收起
    自动换行
    深色代码主题
    复制
    ├─entry
    │  ├─libs/arm64-v8a
    │  │  ├─libplugins_imageformats_qjpeg.so  
    │  │  └─libplugins_platforms_qopenharmony.so    // Qt安装目录'plugins\platforms'HarmonyOS平台插件so
    │  └─src
    │      ├─main
    │      │  ├─cpp
    │      │  │  ├─img                              // 图片文件夹
    │      │  │  │  ├─login.png                     // 登录显示图片
    │      │  │  │  └─user.png                      // 登录头像图片
    │      │  │  ├─clickableuserwidget.cpp          // 点击用户头像cpp文件
    │      │  │  ├─clickableuserwidget.h            // 点击用户头像头文件
    │      │  │  ├─CMakeLists.txt                   // Qt项目CMakeList文件
    │      │  │  ├─image.qrc                        // Qt资源文件
    │      │  │  ├─logindialog.cpp                  // 登录弹窗cpp文件
    │      │  │  ├─logindialog.h                    // 登录弹窗头文件
    │      │  │  ├─main.cpp                         // Qt的主入口
    │      │  │  ├─mainwindow.cpp                   // 主窗口cpp文件
    │      │  │  └─mainwindow.h                     // 主窗口头文件
    │      │  ├─ets
    │      │  │  ├─abilitystage
    │      │  │  │  └─MyAbilityStage.ets
    │      │  │  ├─entryability
    │      │  │  │  └─EntryAbility.ets              // 应用入口
    │      │  │  └─pages
    │      │  │     └─Index.ets                     // 主页面实现
    │      │  ├─resources                           // 应用资源目录
    │      │  └─module.json5                        // 模块级核心配置文件
    │      ├─build-profile.json5                    // 工程结构/构建/定制化配置信息
    │      └─oh-package.json5                       // 描述全局配置
    └─hvigor                                        // 构建环境配置

模块依赖

开源版Qt

参考文档

QDialog
QPixmap
exec
QSystemTrayIcon
QAction
setQuitOnLastWindowClosed

点赞
收藏
回复
1
分享
举报
浏览192 编辑于2026-02-25 07:23广东
全部评论
最多点赞
最新发布
最早发布
写回答
新增插入模板功能
一键使用模板,快速填写内容,轻松发帖~
知道了
  • 为了保障您的信息安全,请勿上传您的敏感个人信息(如您的密码等信息)和您的敏感资产信息(如关键源代码、签名私钥、调试安装包、业务日志等信息),且您需自行承担由此产生的信息泄露等安全风险。
  • 如您发布的内容为转载内容,请注明内容来源。

我要提问题

了解社区公约,与您携手共创和谐专业的开发者社区。