Qt中自定义及控制qDebug的输出

前言

在我们把自己的函数封装成库,然后给别人用时,别人很可能会看到我们库中使用qDebug()打印出来的信息。
这些信息一方面会干扰别人自己的输出,另一方面也会暴露我们自己库的一些细节。但是有时候又的确需要这些信息。
因此,最好有个开关来控制自己库的信息的打印。
这里,我是自己实现了一个debug类,用法也是类似qDebug()那样。仅供参考(推荐使用最新的)

V1版本

class ZyDebugPrivate{

public:
    ZyDebugPrivate()
    {
        if(enablePrint == true)
        {
            mDebugPtr = new QDebug(qDebug());
        }
    }
    ~ZyDebugPrivate()
    {
        if(mDebugPtr != nullptr)
        {
            delete mDebugPtr; // 只有QDebug对象被析构时才会打印
        }
    }
    static ZyDebugPrivate debug() // 这样就实现对象存活期只有一行
    {
        return ZyDebugPrivate();
    }
    
    template<typename T>
    ZyDebugPrivate &operator << (T value)
    {
        if(enablePrint == false)
        {
           QNoDebug() << value;
//           Q_UNUSED(var);
        }
        else
        {
            if(mFirst)
            {
               mDebugPtr->noquote() << QString("DynVision[%1]:").arg(QTime::currentTime().toString("hh:mm:ss.zzz")) << value;
            }
            else
            {
               *mDebugPtr << value;
            }
        }

        mFirst = false;

        return *this;
    }

public:
    static bool enablePrint;

private:
    bool mFirst = true;
    QDebug *mDebugPtr = nullptr;
};
bool ZyDebugPrivate::enablePrint = true;
#define ZyDebug ZyDebugPrivate::debug

V2版本

使用了智能指针,优化了代码结构

class ZyDebugPrivate{
public:
    explicit ZyDebugPrivate(std::shared_ptr<QDebug> ptr)
    {
        mDebugSharedPtr = ptr;
    }
    
    template<typename T>
    ZyDebugPrivate &operator << (T value)
    {
        if(enablePrint == false)
        {
           Q_UNUSED(value);
        }
        else
        {
            if(mFirst)
            {
                mDebugSharedPtr->noquote() << QString("cpp: [DynVision %1]:").arg(QTime::currentTime().toString("hh:mm:ss.zzz")) << value;
            }
            else
            {
                *mDebugSharedPtr << value;
            }
        }
        
        mFirst = false;

        return *this;
    }

public:
    static bool enablePrint;

private:
    bool mFirst = true;
    std::shared_ptr<QDebug> mDebugSharedPtr;
};
#define ZyDebug() ZyDebugPrivate(std::make_shared<QDebug>(qDebug()))

V3版本(存在静态变量的问题)

a.解决了静态变量的重复定义的问题,现在只要把该代码放到一个头文件即可。
b.解决了ZyDebugPrivate::enablePrint = false后,每次ZyDebug()后空一行的问题。

namespace ZyDebugPrivate{
static bool enablePrint = true;
class Private{
public:
    explicit Private(std::shared_ptr<QDebug> ptr)
    {
        mPtr = ptr;
    }
    
    template<typename T>
    Private &operator << (T value)
    {
        if(mPtr != nullptr)
        {
            if(mFirst)
            {
                mPtr->noquote() << QString("cpp: [DynVision %1]:").arg(QTime::currentTime().toString("hh:mm:ss.zzz")) << value;
            }
            else
            {
                *mPtr << value;
            }
        }

        mFirst = false;
        return *this;
    }

private:
    bool mFirst = true;
    std::shared_ptr<QDebug> mPtr;
};
}
#define ZyDebug() ZyDebugPrivate::Private(ZyDebugPrivate::enablePrint ? std::make_shared<QDebug>(qDebug()) : nullptr)

V4版本

V3版本有静态变量的问题,导致无法通过修改enablePrint的值实现全局控制输出(只能控制某个文件范围)。所以,还是老老实实地声明一个类的静态成员变量,然后在cpp文件中定义及初始化吧。

class ZyDebugPrivate{
public:
    explicit ZyDebugPrivate(std::shared_ptr<QDebug> ptr)
    {
        mPtr = ptr;
    }

    template<typename T>
    ZyDebugPrivate &operator << (T value)
    {
        if(mPtr != nullptr)
        {
            if(mFirst)
            {
                mPtr->noquote() << QString("cpp: [MyLib %1]:").arg(QTime::currentTime().toString("hh:mm:ss.zzz")) << value;
            }
            else
            {
                *mPtr << value;
            }
        }

        mFirst = false;
        return *this;
    }

    static bool enablePrint;
private:
    bool mFirst = true;
    std::shared_ptr<QDebug> mPtr;
};
#define ZyDebug() ZyDebugPrivate(ZyDebugPrivate::enablePrint ? std::make_shared<QDebug>(qDebug()) : nullptr)

这句要拿到合适的地方去初始化,比如cpp文件中
//bool ZyDebugPrivate::enablePrint = true;

使用例程

使用:

ZyDebug() << "123" << "-----" << 78989 << 12.3;

输出信息为:

DynVision[16:20:4545.455]: 123 ----- 78989

假如需要关闭输出:

ZyDebugPrivate::enablePrint = false;
  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
好的,这里给你一个简单的 Qt 实现自定义旋钮的案例。 首先,我们需要在 Qt Designer 创建一个自定义控件。打开 Qt Designer 后,选择 "Widget",新建一个空白的窗口,然后在左侧的 "Widget Box" 选择 "Dial" 控件,将其拖拽到窗口。这时候你就可以在窗口看到一个简单的旋钮了。接着,我们需要对其进行自定义。 在左侧的 "Object Inspector" ,选择 "dial" 控件,然后在右侧的 "Property Editor" 修改其属性。比如,你可以修改它的 "minimum" 值和 "maximum" 值,使其能够旋转到任意角度。你还可以修改其样式,使其更符合你的设计需求。 接下来,我们需要在代码实现这个自定义控件。打开 Qt Creator,创建一个新的 Qt Widgets 项目,并在其添加一个自定义控件类。在这个类,我们需要重写一些事件处理函数,以实现自定义旋钮的功能。以下是一个简单的实现: ```cpp class MyDial : public QDial { Q_OBJECT public: MyDial(QWidget* parent = nullptr) : QDial(parent) {} signals: void valueChanged(double value); protected: void mouseMoveEvent(QMouseEvent* event) override { if (event->buttons() & Qt::LeftButton) { QPoint pos = event->pos() - rect().center(); double angle = atan2(-pos.y(), pos.x()) * 180 / M_PI; setValue(static_cast<int>(angle)); emit valueChanged(angle); } } }; ``` 在这个示例,我们重写了 `mouseMoveEvent` 函数,以处理鼠标移动事件。当鼠标左键按下时,我们计算出鼠标相对于旋钮心的角度,然后调用 `setValue` 函数设置旋钮的值,并发出 `valueChanged` 信号。这个信号可以让其他对象在旋钮值发生改变时做出相应的响应。 最后,我们将这个自定义控件添加到主窗口。打开主窗口的头文件,添加以下代码: ```cpp #include "mydial.h" class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget* parent = nullptr) : QMainWindow(parent) { MyDial* dial = new MyDial(this); dial->setGeometry(50, 50, 100, 100); connect(dial, &MyDial::valueChanged, this, &MainWindow::onDialValueChanged); } private slots: void onDialValueChanged(double value) { qDebug() << "Dial value changed:" << value; } }; ``` 在这个示例,我们创建了一个 `MyDial` 对象,并将其添加到主窗口。我们还连接了 `valueChanged` 信号,以在旋钮值发生改变时输出调试信息。 这就是一个简单的 Qt 实现自定义旋钮的案例。希望对你有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值