qt实现命令行查询程序相关信息QCommandLineParser,QCommandLineOption的使用

646 阅读3分钟

我们知道,程序是可以通过命令行打开的,做法是打开运行cmd,打开命令行窗口,然后输入程序的完整路径就可以打开程序,比如在我的电脑路径F:\QTCode\TestCode\QtUseOpenGlTest\build-hellogl2-Desktop_Qt_5_14_2_MSVC2017_64bit-Debug\debug下有个hellogl2.exe程序,通过命令行打开方式如下:

按下win+R——输入cmd——按回车出现如下界面: 

 然后输入F:\QTCode\TestCode\QtUseOpenGlTest\build-hellogl2-Desktop_Qt_5_14_2_MSVC2017_64bit-Debug\debug\hellogl2.exe,程序就运行起来了

 那么如果我想要在运行程序之前查看一下这个程序的相关信息怎么办呢?

我们可以通过qt的QCommandLineOption类来给程序添加一些命令行可以查看的信息,代码如下:

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QCoreApplication::setApplicationName("Qt Hello GL 2 Example");
    QCoreApplication::setOrganizationName("QtProject");
    QCoreApplication::setApplicationVersion(QT_VERSION_STR);
    QCommandLineParser parser;
    parser.setApplicationDescription(QCoreApplication::applicationName());
    parser.addHelpOption();
    parser.addVersionOption();
    QCommandLineOption multipleSampleOption("multisample", "Multisampling");
    parser.addOption(multipleSampleOption);
    QCommandLineOption coreProfileOption("coreprofile", "Use core profile");
    parser.addOption(coreProfileOption);
    QCommandLineOption transparentOption("transparent", "Transparent window");
    parser.addOption(transparentOption);

    parser.process(app);

    QSurfaceFormat fmt;
    fmt.setDepthBufferSize(24);
    if (parser.isSet(multipleSampleOption))
        fmt.setSamples(4);
    if (parser.isSet(coreProfileOption)) {
        fmt.setVersion(3, 2);
        fmt.setProfile(QSurfaceFormat::CoreProfile);
    }
    QSurfaceFormat::setDefaultFormat(fmt);
    //TODO:程序主窗口显示相关代码
Window mainWindow;
    //GLWidget::setTransparent(parser.isSet(transparentOption));
    GLWidget::setTransparent(true);
    if (GLWidget::isTransparent()) {
        mainWindow.setWindowFlags(Qt::FramelessWindowHint|Qt::WindowStaysOnTopHint);//设置无窗口框架边界
        mainWindow.setAttribute(Qt::WA_TranslucentBackground);
        //mainWindow.setAttribute(Qt::WA_NoSystemBackground, false);

    }
    mainWindow.resize(mainWindow.sizeHint());
   int desktopArea = QApplication::desktop()->width() *
                    QApplication::desktop()->height();
    int widgetArea = mainWindow.width() * mainWindow.height();
    if (((float)widgetArea / (float)desktopArea) < 0.75f)
        mainWindow.show();
    else
       mainWindow.showMaximized();
    mainWindow.resize(QSize(300,300));
    mainWindow.show();
    return app.exec();
}

然后在命令行中查看相关信息的方式如下:

 输入F:\QTCode\TestCode\QtUseOpenGlTest\build-hellogl2-Desktop_Qt_5_14_2_MSVC2017_64bit-Debug\debug\hellogl2.exe -h,就自动会跳出一个界面,显示帮助信息,其他还可以输入-v  --multisample --transparent等

其实这是个qt自带的例程,是关于opengl的,里面的glwidget类写的很好,很有参考价值,有兴趣的可以看看,具体代码如下: `#include "glwidget.h" #include #include #include #include <math.h>

bool GLWidget::m_transparent = false;

GLWidget::GLWidget(QWidget *parent) : QOpenGLWidget(parent), m_xRot(0), m_yRot(0), m_zRot(0), m_program(0), m_bMidButtonPressed(false) { m_core = QSurfaceFormat::defaultFormat().profile() == QSurfaceFormat::CoreProfile; // --transparent causes the clear color to be transparent. Therefore, on systems that // support it, the widget will become transparent apart from the logo. if (m_transparent) { QSurfaceFormat fmt = format(); fmt.setAlphaBufferSize(8); setFormat(fmt); } }

GLWidget::~GLWidget() { cleanup(); }

QSize GLWidget::minimumSizeHint() const { return QSize(50, 50); }

QSize GLWidget::sizeHint() const { return QSize(400, 400); }

static void qNormalizeAngle(int &angle) { while (angle < 0) angle += 360 * 16; while (angle > 360 * 16) angle -= 360 * 16; }

void GLWidget::setXRotation(int angle) { qNormalizeAngle(angle); if (angle != m_xRot) { m_xRot = angle; emit xRotationChanged(angle); update(); } }

void GLWidget::setYRotation(int angle) { qNormalizeAngle(angle); if (angle != m_yRot) { m_yRot = angle; emit yRotationChanged(angle); update(); } }

void GLWidget::setZRotation(int angle) { qNormalizeAngle(angle); if (angle != m_zRot) { m_zRot = angle; emit zRotationChanged(angle); update(); } }

void GLWidget::cleanup() { if (m_program == nullptr) return; makeCurrent(); m_logoVbo.destroy(); delete m_program; m_program = 0; doneCurrent(); }

static const char *vertexShaderSourceCore = "#version 150\n" "in vec4 vertex;\n" "in vec3 normal;\n" "out vec3 vert;\n" "out vec3 vertNormal;\n" "uniform mat4 projMatrix;\n" "uniform mat4 mvMatrix;\n" "uniform mat3 normalMatrix;\n" "void main() {\n" " vert = vertex.xyz;\n" " vertNormal = normalMatrix * normal;\n" " gl_Position = projMatrix * mvMatrix * vertex;\n" "}\n";

static const char *fragmentShaderSourceCore = "#version 150\n" "in highp vec3 vert;\n" "in highp vec3 vertNormal;\n" "out highp vec4 fragColor;\n" "uniform highp vec3 lightPos;\n" "void main() {\n" " highp vec3 L = normalize(lightPos - vert);\n" " highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n" " highp vec3 color = vec3(0.39, 1.0, 0.0);\n" " highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n" " fragColor = vec4(col, 1.0);\n" "}\n";

static const char *vertexShaderSource = "attribute vec4 vertex;\n" "attribute vec3 normal;\n" "varying vec3 vert;\n" "varying vec3 vertNormal;\n" "uniform mat4 projMatrix;\n" "uniform mat4 mvMatrix;\n" "uniform mat3 normalMatrix;\n" "void main() {\n" " vert = vertex.xyz;\n" " vertNormal = normalMatrix * normal;\n" " gl_Position = projMatrix * mvMatrix * vertex;\n" "}\n";

static const char *fragmentShaderSource = "varying highp vec3 vert;\n" "varying highp vec3 vertNormal;\n" "uniform highp vec3 lightPos;\n" "void main() {\n" " highp vec3 L = normalize(lightPos - vert);\n" " highp float NL = max(dot(normalize(vertNormal), L), 0.0);\n" " highp vec3 color = vec3(0.39, 1.0, 0.0);\n" " highp vec3 col = clamp(color * 0.2 + color * 0.8 * NL, 0.0, 1.0);\n" " gl_FragColor = vec4(col, 1.0);\n" "}\n";

void GLWidget::initializeGL() { // In this example the widget's corresponding top-level window can change // several times during the widget's lifetime. Whenever this happens, the // QOpenGLWidget's associated context is destroyed and a new one is created. // Therefore we have to be prepared to clean up the resources on the // aboutToBeDestroyed() signal, instead of the destructor. The emission of // the signal will be followed by an invocation of initializeGL() where we // can recreate all resources. connect(context(), &QOpenGLContext::aboutToBeDestroyed, this, &GLWidget::cleanup);

initializeOpenGLFunctions();
glClearColor(0, 0, 0, m_transparent ? 0 : 1);

m_program = new QOpenGLShaderProgram;
m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_core ? vertexShaderSourceCore : vertexShaderSource);
m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_core ? fragmentShaderSourceCore : fragmentShaderSource);
m_program->bindAttributeLocation("vertex", 0);
m_program->bindAttributeLocation("normal", 1);
m_program->link();

m_program->bind();
m_projMatrixLoc = m_program->uniformLocation("projMatrix");
m_mvMatrixLoc = m_program->uniformLocation("mvMatrix");
m_normalMatrixLoc = m_program->uniformLocation("normalMatrix");
m_lightPosLoc = m_program->uniformLocation("lightPos");

// Create a vertex array object. In OpenGL ES 2.0 and OpenGL 2.x
// implementations this is optional and support may not be present
// at all. Nonetheless the below code works in all cases and makes
// sure there is a VAO when one is needed.
m_vao.create();
QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);

// Setup our vertex buffer object.
m_logoVbo.create();
m_logoVbo.bind();
m_logoVbo.allocate(m_logo.constData(), m_logo.count() * sizeof(GLfloat));

// Store the vertex attribute bindings for the program.
setupVertexAttribs();

// Our camera never changes in this example.
m_camera.setToIdentity();
m_camera.translate(0, 0, -1);

// Light position is fixed.
m_program->setUniformValue(m_lightPosLoc, QVector3D(0, 0, 70));

m_program->release();

}

void GLWidget::setupVertexAttribs() { m_logoVbo.bind(); QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); f->glEnableVertexAttribArray(0); f->glEnableVertexAttribArray(1); f->glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), 0); f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), reinterpret_cast<void *>(3 * sizeof(GLfloat))); m_logoVbo.release(); }

void GLWidget::paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE);

m_world.setToIdentity();
m_world.rotate(180.0f - (m_xRot / 16.0f), 1, 0, 0);
m_world.rotate(m_yRot / 16.0f, 0, 1, 0);
m_world.rotate(m_zRot / 16.0f, 0, 0, 1);

QOpenGLVertexArrayObject::Binder vaoBinder(&m_vao);
m_program->bind();
m_program->setUniformValue(m_projMatrixLoc, m_proj);
m_program->setUniformValue(m_mvMatrixLoc, m_camera * m_world);
QMatrix3x3 normalMatrix = m_world.normalMatrix();
m_program->setUniformValue(m_normalMatrixLoc, normalMatrix);

glDrawArrays(GL_TRIANGLES, 0, m_logo.vertexCount());

m_program->release();

}

void GLWidget::resizeGL(int w, int h) { m_proj.setToIdentity(); m_proj.perspective(45.0f, GLfloat(w) / h, 0.01f, 100.0f); }

void GLWidget::mousePressEvent(QMouseEvent *event) { if(event->button()==Qt::MidButton) { m_bMidButtonPressed = true; } else { m_bMidButtonPressed = false; } m_lastPos = event->pos(); }

void GLWidget::mouseReleaseEvent(QMouseEvent *event) { m_bMidButtonPressed = false; }

void GLWidget::mouseMoveEvent(QMouseEvent *event) { if(m_bMidButtonPressed) { int dx = event->x() - m_lastPos.x(); int dy = event->y() - m_lastPos.y(); emit midKeyMoveDis(QPoint(dx,dy)); } else { int dx = event->x() - m_lastPos.x(); int dy = event->y() - m_lastPos.y(); if (event->buttons() & Qt::LeftButton) { setXRotation(m_xRot + 8 * dy); setYRotation(m_yRot + 8 * dx); } else if (event->buttons() & Qt::RightButton) { setXRotation(m_xRot + 8 * dy); setZRotation(m_zRot + 8 * dx); } m_lastPos = event->pos(); } } `