【Qt项目实战】使用脚本拓展CPP应用程序(2)——Lua脚本及编辑器

考古 《【Qt项目实战 】:使用脚本拓展CPP应用程序(1)------Lua脚本及编辑器》

一、LuaBridge

最近在项目的某个模块再次使用Lua作为程序拓展语言,开发了一些新的功能。

这里借助 LuaBridge 轻松实现Qt调用C++类成员函数及成员对象等功能;在(1)中,我们更多展示的是使用CFunction的方式,提供接口给Lua脚本调用。
LuaBridge https://github.com/DeHby/LuaBridge

使用及其简单,推荐指数5颗星

二、如何在Qt控件中展示Lua打印消息

我们都很清楚,print 函数可以在lua脚本中轻松实现打印。但是要将打印结果重定向到Qt控件中,新手朋友可能会稍微有点烦恼。

这里提供两种方法,一种简单,另一种进阶:

2.1、定义自己的print函数,并使用qDebug()实现打印输出。

Qt支持qDebug() 的输出重定向。

在 Qt 中,qDebug() 是用于输出调试信息的函数。默认情况下,它将信息输出到标准输出(通常是控制台)。如果你想重定向 qDebug() 的输出,可以使用 QDebug 类的 setOutput 方法,或者通过重定向 qInstallMessageHandler 函数来实现。

方法 1: 使用 qInstallMessageHandler

你可以通过安装自定义的消息处理程序来重定向 qDebug() 的输出。以下是一个示例,展示如何将 qDebug() 的输出重定向到文件:

cpp 复制代码
#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QTextStream>

void customMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg) {
    QFile outFile("debug_output.txt");
    if (outFile.open(QIODevice::Append | QIODevice::Text)) {
        QTextStream ts(&outFile);
        switch (type) {
            case QtDebugMsg:
                ts << "Debug: " << msg << "\n";
                break;
            case QtWarningMsg:
                ts << "Warning: " << msg << "\n";
                break;
            case QtCriticalMsg:
                ts << "Critical: " << msg << "\n";
                break;
            case QtFatalMsg:
                ts << "Fatal: " << msg << "\n";
                abort(); // 终止程序
        }
        outFile.close();
    }
}

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    // 安装自定义消息处理程序
    qInstallMessageHandler(customMessageHandler);

    // 测试 qDebug 输出
    qDebug() << "This is a debug message.";
    qWarning() << "This is a warning message.";
    qCritical() << "This is a critical message.";

    return a.exec();
}

说明

  1. 自定义消息处理程序 : customMessageHandler 函数根据消息类型将输出写入文件 debug_output.txt。
  2. qInstallMessageHandler : 在 main 函数中调用此函数来安装自定义的消息处理程序。
  3. 消息类型: 根据消息类型(调试、警告、严重、致命)输出不同的前缀。

方法 2: 使用 QDebug 的 setOutput 方法

如果你想将 qDebug() 的输出重定向到其他输出流(如 QFile),可以使用 QDebug 的构造函数来实现:

cpp 复制代码
#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QTextStream>

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    QFile outFile("debug_output.txt");
    if (outFile.open(QIODevice::WriteOnly | QIODevice::Text)) {
        QTextStream ts(&outFile);
        QDebug debug(&ts); // 将 QDebug 输出重定向到 QTextStream

        debug << "This is a debug message.";
        debug << "Another debug message.";

        outFile.close();
    }

    return a.exec();
}

说明

  1. QFile 和 QTextStream: 创建一个文件并打开以写入。
  2. QDebug 构造函数 : 使用 QDebug debug(&ts); 将输出重定向到 QTextStream,从而写入文件。

展开你的想象,既然可以定向到文件,自然可以定向到控件。通过信号和槽可以轻松的实现~ 这里比较简单,只提供思路。

2.2 直接在print函数中发送信号(啥!Lua调用的C++函数也可以发送信号~)

答案,是肯定的。搞那么复杂,我们只是想在Lua调用print方法时,可以将输出信息展示在窗口控件上,直接通过信号和槽函数绑定自然是最简单的。

这里给个示例:

cpp 复制代码
int MyClass::luaPrint(lua_State *L) {
    // 获取全局变量 qtBridgeLuaInstance
    lua_getglobal(L, "qtBridgeLuaInstance");
    QtBridgeLua *instance = static_cast<MyClass*>(lua_touserdata(L, -1));
    lua_pop(L, 1); // 弹出 qtBridgeLuaInstance

    if (!instance) {
        qDebug() << "QtBridgeLua instance is null!";
        return 0; // 返回 0,避免崩溃
    }

    int n = lua_gettop(L); // 获取参数个数
    QString output;

    for (int i = 1; i <= n; ++i) {
        if (lua_isstring(L, i)) { // 检查参数是否为字符串
            if (i > 1) output += " "; // 添加空格分隔
            output += QString::fromUtf8(lua_tostring(L, i)); // 获取字符串参数
        } else {
            qDebug() << "Argument" << i << "is not a string!";
        }
    }

    qDebug() << "luaprin==>" << instance;
    emit instance->lua_print_info(output); // 发射信号
    return 0; // 返回值
}
cpp 复制代码
signals:
    void lua_print_info(QString s);

多么轻松且自由~

OKK,下班下班。且到这里~

相关推荐
caoliaoerweima11 小时前
草料二维码小程序上线活码编辑器:手机上也能编辑活码了
智能手机·小程序·编辑器·草料二维码
努力努力再努力wz1 天前
【Lua 进阶系列】从 C++ 对象到 Lua 变量:一文理解 userdata、Lua 栈与元表绑定机制
c++·junit·lua
慧都产品智能化1 天前
Qt 表格升级攻略:复用已有编辑器,减少重复开发
c++·qt·编辑器·qt6.3
ShineWinsu1 天前
对于Qt:QTableWidget常见属性以及QTableWidgetItem类的解析
开发语言·c++·qt·gui·客户端·表格·qtablewidget
ShineWinsu1 天前
对于Qt:QListWidget常见属性以及QListWidgetItem类的解析
开发语言·c++·qt·客户端·列表·qlistwidget·qlistwidgetitem
阿卡好可爱1 天前
Lua 热更新不生效:改完文件线上仍是旧逻辑,package.loaded 与 upvalue 重绑定详解
数据结构·分布式·后端·架构·lua
Joy T1 天前
Redis Lua 原子限流:Lua 脚本、竞态条件与并发控制
数据库·redis·lua·限流·竞态条件·redis scripting
ShineWinsu2 天前
对于Qt:QDial常见属性以及信号的解析
开发语言·c++·qt·gui·客户端·旋钮·qdial
DFT计算杂谈2 天前
可DIY布里渊区图像绘制编辑器
人工智能·机器学习·语言模型·矩阵·编辑器
宛 禾2 天前
Qt 事件系统完全指南:从事件循环到实战避坑
qt