如何从我的代码中确定我的应用程序是否从 Qt Creator 启动(通过“F5”或“Ctrl + R”)?
我想知道这一点的原因是因为我只想在直接从可执行文件启动应用程序时创建自己的调试消息处理程序(使用 qInstallMessageHandler()) 。由于 Qt 只允许一个消息处理程序,我不想在从 Qt Creator 启动时创建自己的消息处理程序,否则我无法在 Qt Creators 自己的调试控制台中看到调试消息。
如何从我的代码中确定我的应用程序是否从 Qt Creator 启动(通过“F5”或“Ctrl + R”)?
我想知道这一点的原因是因为我只想在直接从可执行文件启动应用程序时创建自己的调试消息处理程序(使用 qInstallMessageHandler()) 。由于 Qt 只允许一个消息处理程序,我不想在从 Qt Creator 启动时创建自己的消息处理程序,否则我无法在 Qt Creators 自己的调试控制台中看到调试消息。
我认为没有一种简单的方法可以检测到这一点。不过,您可以在 QtCreator 的运行设置中添加一个命令行参数,并在运行时检查它。
我有两种可能的解决方案:
检查父进程(或父进程的父进程)的名称
有多种方法可以做到这一点:在 Posix(mingw、linux 等)下,你有 getppid()。在 Windows 下您可以检查名称是否具有Psapi或其他进程处理功能。我过去曾出于其他目的这样做过,只要进程名称不变,它就可以可靠地工作。或者,您可以检查窗口名称。不幸的是,这些解决方案都不是“Qt-Native”。
仅当从 Qt creator 启动时才提供命令行参数
如果您使用库来扫描命令行参数,这可能是最简单的解决方案。我通常使用 Boost Program Options(Google 那里)。您可以创建一个命令行参数,如“--console-log”,指定将日志记录输出到控制台。此处记录了从 Qt Creator 中设置该选项。这可能是最“Qt-Native”的解决方案。如果你使用 Qt 函数来解析命令行,它是 100% Qt。
您可以尝试IsDebuggerPresent或仅使用 QDebug 并使用QT Creator 外部的debugview检查调试消息。
您应该 google qInstallMessageHandler 了解更多信息。
但是这里有定义:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtGui>
#include <QtWidgets>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
static void myMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
// If you're running lots of threads you'll need to do some research to
// determine if you need to make this synchronized (i.e. locked)
if(staticTextEdit) {
staticTextEdit->appendPlainText(msg + "\n");
}
}
private slots:
void on_pushButton_clicked();
private:
// There's lots of different ways to do this ... this was the quickest way for me.
static QPlainTextEdit* staticTextEdit;
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
以下是声明:
#include "mainwindow.h"
#include "ui_mainwindow.h"
QPlainTextEdit* MainWindow::staticTextEdit = NULL;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
staticTextEdit = ui->plainTextEdit;
qInstallMessageHandler(MainWindow::myMessageHandler);
}
MainWindow::~MainWindow()
{
delete ui;
}
// I'm using QtCreator to help create my slots. =).
void MainWindow::on_pushButton_clicked()
{
qDebug() << "CLICKED";
}
不确定这是否适用于 PC,但在 OSX 下,当 Qt Creator 启动应用程序时,它会从开发构建路径执行;您可以通过以下方式获取当前的启动路径:
QString expath = QCoreApplication::applicationDirPath();
获取它,通过 转储它qDebug()
,然后查看从 Qt 启动时的运行位置。只要这不是您在 Qt 中未启动应用程序时运行应用程序的位置,这应该可以工作。
在 Qt Creator 中以发布模式构建和运行时,我从 qDebug() 中得到了这个:
"/Users/fyngyrz/build-iToolBox-Desktop_Qt_5_8_0_clang_64bit-Release/iToolBox.app/Contents/MacOS/iToolBox"
所以对我来说,在构建我的应用程序时,iToolBox
我会像这样进行检测:
if (expath.indexOf("build-iToolBox-Desktop") != -1) // if we're running from inside Qt
{
}
else // we're not running from inside qt
{
}
Qt 构建的发布和构建路径默认是不同的;因此,如果您需要它在发布和调试环境中工作,您可能需要对路径进行两次检查而不是一次检查,具体取决于您正在搜索的内容。
如果您将此方法合并到您的应用程序中,并且代码将在发布版本中保持不变,请确保不要在搜索字符串中包含任何包含您不想共享的任何信息的内容,例如您的真实姓名成为某些操作系统下路径的一部分,具体取决于您设置用户帐户的方式。
这是一个手动解决方案。
在您的 .pro 文件中定义一个宏......
# To turn on remove the comment marker '#'
# isEmpty(LAUNCH_FROM_IDE):LAUNCH_FROM_IDE = 1
!isEmpty(LAUNCH_FROM_IDE) {
DEFINES += APP_LAUNCH_FROM_IDE
}
并根据需要在您的标题/源中使用...
#ifdef APP_LAUNCH_FROM_IDE
...
#endif
就这样