【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: 使用 QDebugsetOutput 方法

如果你想将 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. QFileQTextStream: 创建一个文件并打开以写入。
  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,下班下班。且到这里~

相关推荐
用户805533698033 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner3 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz8 天前
QML Hello World 入门示例
qt
xcyxiner11 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner11 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner12 天前
DicomViewer (添加模型类)3
qt
xcyxiner12 天前
DicomViewer (目录调整) 2
qt
xcyxiner12 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
VidDown14 天前
VidDown 工具站:免费、本地优先的开发者工具箱
javascript·编辑器·音视频·视频编解码·视频
xingpanvip14 天前
星盘接口开发文档:本命盘接口指南
android·开发语言·css·php·lua