How to change the build/ window name of application?
-
I had cloned a drone application's repository in Qtcreator and want to change the application's build or window name located on the top left corner of the window.
-
I think you are talking about the title that appears on the application's main window title bar. You change that with QWidget::setWindowTitle(). If you are using Qt Creator or Designer to make the UI then the window title is accessible as a property of the main widget (and will generate code calling setWindowTitle).
-
If I am trying to write this code following error is coming-
-
@himanshu-chauhan Please post code and error messages as text.
You need to call that meathod on your top level widget. Usually it is a QMainWindow instance. -
@jsulm
Ther error is-
C:\Users\hc243\PROJECT_ASSIGNEMENT\Qgroundcontrol\src\main.cc:241: error: C2352: 'QWidget::setWindowTitle': a call of a non-static member function requires an object
D:\QT\5.15.2\msvc2019_64\include\QtWidgets/qwidget.h(365): note: see declaration of 'QWidget::setWindowTitle'What do mean by "top level widget".
-
@himanshu-chauhan said in How to change the build/ window name of application?:
What do mean by "top level widget".
I mean the widget representing your main window.
Please post the whole content of your main() function then I can tell you what exactly you need to do.The error message tells you that setWindowTitle() is a non static method, so you need an object on which you call it (basic C++).
-
@jsulm
this is the whole main.cc file-#include <QtGlobal>
#include <QApplication>
#include <QIcon>
#include <QSslSocket>
#include <QMessageBox>
#include <QProcessEnvironment>
#include <QHostAddress>
#include <QUdpSocket>
#include <QtPlugin>
#include <QStringListModel>#include "QGC.h"
#include "QGCApplication.h"
#include "AppMessages.h"
#include "SDL_video.h"#ifndef NO_SERIAL_LINK
#include "SerialLink.h"
#endif#ifndef mobile
#include "QGCSerialPortInfo.h"
#include "RunGuard.h"
#ifndef NO_SERIAL_LINK
#include <QSerialPort>
#endif
#endif#ifdef UNITTEST_BUILD
#include "UnitTest.h"
#endif#ifdef QT_DEBUG
#include "CmdLineOptParser.h"
#ifdef Q_OS_WIN
#include <crtdbg.h>
#endif
#endif#ifdef QGC_ENABLE_BLUETOOTH
#include <QtBluetooth/QBluetoothSocket>
#endif#include <iostream>
#include "QGCMapEngine.h"/* SDL does ugly things to main() */
#ifdef main
#undef main
#endif#ifndef mobile
#ifndef NO_SERIAL_LINK
Q_DECLARE_METATYPE(QGCSerialPortInfo)
#endif
#endif#ifdef Q_OS_WIN
#include <windows.h>
/// @brief CRT Report Hook installed using _CrtSetReportHook. We install this hook when
/// we don't want asserts to pop a dialog on windows.
int WindowsCrtReportHook(int reportType, char* message, int* returnValue)
{
Q_UNUSED(reportType);std::cerr << message << std::endl; // Output message to stderr *returnValue = 0; // Don't break into debugger return true; // We handled this fully ourselves
}
#endif
#if defined(android)
#include <jni.h>
#include "JoystickAndroid.h"
#if defined(QGC_ENABLE_PAIRING)
#include "PairingManager.h"
#endif
#if !defined(NO_SERIAL_LINK)
#include "qserialport.h"
#endifstatic jobject _class_loader = nullptr;
static jobject _context = nullptr;//-----------------------------------------------------------------------------
extern "C" {
void gst_amc_jni_set_java_vm(JavaVM *java_vm);jobject gst_android_get_application_class_loader(void) { return _class_loader; }
}
//-----------------------------------------------------------------------------
static void
gst_android_init(JNIEnv* env, jobject context)
{
jobject class_loader = nullptr;jclass context_cls = env->GetObjectClass(context); if (!context_cls) { return; } jmethodID get_class_loader_id = env->GetMethodID(context_cls, "getClassLoader", "()Ljava/lang/ClassLoader;"); if (env->ExceptionCheck()) { env->ExceptionDescribe(); env->ExceptionClear(); return; } class_loader = env->CallObjectMethod(context, get_class_loader_id); if (env->ExceptionCheck()) { env->ExceptionDescribe(); env->ExceptionClear(); return; } _context = env->NewGlobalRef(context); _class_loader = env->NewGlobalRef (class_loader);
}
//-----------------------------------------------------------------------------
static const char kJniClassName[] {"org/mavlink/qgroundcontrol/QGCActivity"};void setNativeMethods(void)
{
JNINativeMethod javaMethods[] {
{"nativeInit", "()V", reinterpret_cast<void *>(gst_android_init)}
};QAndroidJniEnvironment jniEnv; if (jniEnv->ExceptionCheck()) { jniEnv->ExceptionDescribe(); jniEnv->ExceptionClear(); } jclass objectClass = jniEnv->FindClass(kJniClassName); if(!objectClass) { qWarning() << "Couldn't find class:" << kJniClassName; return; } jint val = jniEnv->RegisterNatives(objectClass, javaMethods, sizeof(javaMethods) / sizeof(javaMethods[0])); if (val < 0) { qWarning() << "Error registering methods: " << val; } else { qDebug() << "Main Native Functions Registered"; } if (jniEnv->ExceptionCheck()) { jniEnv->ExceptionDescribe(); jniEnv->ExceptionClear(); }
}
//-----------------------------------------------------------------------------
jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
Q_UNUSED(reserved);JNIEnv* env; if (vm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) { return -1; } setNativeMethods();
#if defined(QGC_GST_STREAMING)
// Tell the androidmedia plugin about the Java VM
gst_amc_jni_set_java_vm(vm);
#endif#if !defined(NO_SERIAL_LINK)
QSerialPort::setNativeMethods();
#endifJoystickAndroid::setNativeMethods();
#if defined(QGC_ENABLE_PAIRING)
PairingManager::setNativeMethods();
#endifreturn JNI_VERSION_1_6;
}
#endif//-----------------------------------------------------------------------------
#ifdef android
#include <QtAndroid>
bool checkAndroidWritePermission() {
QtAndroid::PermissionResult r = QtAndroid::checkPermission("android.permission.WRITE_EXTERNAL_STORAGE");
if(r == QtAndroid::PermissionResult::Denied) {
QtAndroid::requestPermissionsSync( QStringList() << "android.permission.WRITE_EXTERNAL_STORAGE" );
r = QtAndroid::checkPermission("android.permission.WRITE_EXTERNAL_STORAGE");
if(r == QtAndroid::PermissionResult::Denied) {
return false;
}
}
return true;
}
#endif// To shut down QGC on Ctrl+C on Linux
#ifdef Q_OS_LINUX
#include <csignal>void sigHandler(int s)
{
std::signal(s, SIG_DFL);
QApplication::instance()->quit();
}#endif /* Q_OS_LINUX */
//-----------------------------------------------------------------------------
/**
@brief Starts the application@param argc Number of commandline arguments
@param argv Commandline arguments
@return exit code, 0 for normal exit and !=0 for error cases
*/int main(int argc, char *argv[])
{
QWidget::setWindowTitle("Title1");
#ifndef mobile
// We make the runguard key different for custom and non custom
// builds, so they can be executed together in the same device.
// Stable and Daily have same QGC_APPLICATION_NAME so they would
// not be able to run at the same time
QString runguardString(QGC_APPLICATION_NAME);
runguardString.append("RunGuardKey");RunGuard guard(runguardString); if (!guard.tryToRun()) { // QApplication is necessary to use QMessageBox QApplication errorApp(argc, argv); QMessageBox::critical(nullptr, QObject::tr("Error"), QObject::tr("A second instance of %1 is already running. Please close the other instance and try again.").arg(QGC_APPLICATION_NAME) ); return -1; }
#endif
//-- Record boot time QGC::initTimer();
#ifdef Q_OS_UNIX
//Force writing to the console on UNIX/BSD devices
if (!qEnvironmentVariableIsSet("QT_LOGGING_TO_CONSOLE"))
qputenv("QT_LOGGING_TO_CONSOLE", "1");
#endif// install the message handler AppMessages::installHandler();
#ifdef Q_OS_MAC
#ifndef ios
// Prevent Apple's app nap from screwing us over
// tip: the domain can be cross-checked on the command line with <defaults domains>
QProcess::execute("defaults", {"write org.qgroundcontrol.qgroundcontrol NSAppSleepDisabled -bool YES"});
#endif
#endif#ifdef Q_OS_WIN
// Set our own OpenGL buglist
qputenv("QT_OPENGL_BUGLIST", ":/opengl/resources/opengl/buglist.json");// Allow for command line override of renderer for (int i = 0; i < argc; i++) { const QString arg(argv[i]); if (arg == QStringLiteral("-angle")) { QCoreApplication::setAttribute(Qt::AA_UseOpenGLES); break; } else if (arg == QStringLiteral("-swrast")) { QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL); break; } }
#endif
#ifdef Q_OS_LINUX
std::signal(SIGINT, sigHandler);
std::signal(SIGTERM, sigHandler);
#endif /* Q_OS_LINUX */// The following calls to qRegisterMetaType are done to silence debug output which warns // that we use these types in signals, and without calling qRegisterMetaType we can't queue // these signals. In general we don't queue these signals, but we do what the warning says // anyway to silence the debug output.
#ifndef NO_SERIAL_LINK
qRegisterMetaTypeQSerialPort::SerialPortError();
#endif
#ifdef QGC_ENABLE_BLUETOOTH
qRegisterMetaTypeQBluetoothSocket::SocketError();
qRegisterMetaType<QBluetoothServiceInfo>();
#endif
qRegisterMetaTypeQAbstractSocket::SocketError();
#ifndef mobile
#ifndef NO_SERIAL_LINK
qRegisterMetaType<QGCSerialPortInfo>();
#endif
#endifqRegisterMetaType<Vehicle::MavCmdResultFailureCode_t>("Vehicle::MavCmdResultFailureCode_t"); // We statically link our own QtLocation plugin
#ifdef Q_OS_WIN
// In Windows, the compiler doesn't see the use of the class created by Q_IMPORT_PLUGIN
#pragma warning( disable : 4930 4101 )
#endifQ_IMPORT_PLUGIN(QGeoServiceProviderFactoryQGC) bool runUnitTests = false; // Run unit tests
#ifdef QT_DEBUG
// We parse a small set of command line options here prior to QGCApplication in order to handle the ones
// which need to be handled before a QApplication object is started.bool stressUnitTests = false; // Stress test unit tests bool quietWindowsAsserts = false; // Don't let asserts pop dialog boxes QString unitTestOptions; CmdLineOpt_t rgCmdLineOptions[] = { { "--unittest", &runUnitTests, &unitTestOptions }, { "--unittest-stress", &stressUnitTests, &unitTestOptions }, { "--no-windows-assert-ui", &quietWindowsAsserts, nullptr }, // Add additional command line option flags here }; ParseCmdLineOptions(argc, argv, rgCmdLineOptions, sizeof(rgCmdLineOptions)/sizeof(rgCmdLineOptions[0]), false); if (stressUnitTests) { runUnitTests = true; } if (quietWindowsAsserts) {
#ifdef Q_OS_WIN
_CrtSetReportHook(WindowsCrtReportHook);
#endif
}#ifdef Q_OS_WIN
if (runUnitTests) {
// Don't pop up Windows Error Reporting dialog when app crashes. This prevents TeamCity from
// hanging.
DWORD dwMode = SetErrorMode(SEM_NOGPFAULTERRORBOX);
SetErrorMode(dwMode | SEM_NOGPFAULTERRORBOX);
}
#endif
#endif // QT_DEBUGQCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); QGCApplication* app = new QGCApplication(argc, argv, runUnitTests); Q_CHECK_PTR(app); if(app->isErrorState()) { app->exec(); return -1; }
#ifdef Q_OS_LINUX
QApplication::setWindowIcon(QIcon(":/res/resources/icons/qgroundcontrol.ico"));
#endif /* Q_OS_LINUX */// There appears to be a threading issue in qRegisterMetaType which can cause it to throw a qWarning // about duplicate type converters. This is caused by a race condition in the Qt code. Still working // with them on tracking down the bug. For now we register the type which is giving us problems here // while we only have the main thread. That should prevent it from hitting the race condition later // on in the code. qRegisterMetaType<QList<QPair<QByteArray,QByteArray> > >(); app->_initCommon(); //-- Initialize Cache System getQGCMapEngine()->init(); int exitCode = 0;
#ifdef UNITTEST_BUILD
if (runUnitTests) {
for (int i=0; i < (stressUnitTests ? 20 : 1); i++) {
if (!app->_initForUnitTests()) {
return -1;
}// Run the test int failures = UnitTest::run(unitTestOptions); if (failures == 0) { qDebug() << "ALL TESTS PASSED"; exitCode = 0; } else { qDebug() << failures << " TESTS FAILED!"; exitCode = -failures; break; } } } else
#endif
{#ifdef android
checkAndroidWritePermission();
#endif
if (!app->_initForNormalAppBoot()) {
return -1;
}
exitCode = app->exec();
}app->_shutdown(); delete app; //-- Shutdown Cache System destroyMapEngine(); qDebug() << "After app delete"; return exitCode;
}
-
This is a lot of code and I can't see where you're creating any windows?
Does QGCApplication create the window?
Does your application have a QMainWindow instance? -
I am new to the platform so I can't really say where the window is been created but it seems that QGCApplication is doing that work. I found following code in it-
bool QGCApplication::_initForNormalAppBoot()
{
QSettings settings;_qmlAppEngine = toolbox()->corePlugin()->createQmlApplicationEngine(this); toolbox()->corePlugin()->createRootWindow(_qmlAppEngine); // Image provider for PX4 Flow QQuickImageProvider* pImgProvider = dynamic_cast<QQuickImageProvider*>(qgcApp()->toolbox()->imageProvider()); _qmlAppEngine->addImageProvider(QStringLiteral("QGCImages"), pImgProvider); QQuickWindow* rootWindow = qgcApp()->mainRootWindow(); if (rootWindow) { rootWindow->scheduleRenderJob (new FinishVideoInitialization (toolbox()->videoManager()), QQuickWindow::BeforeSynchronizingStage); }
}
-
QQuickWindow* rootWindow = qgcApp()->mainRootWindow(); if (rootWindow) { rootWindow->setTitle("YOUR TITLE HERE");
-
Thank you very much, it is working now.
-
I managed to change it, it's inside the "qgroundcontrol.pro" file. This is for anyone who wants to change the name of the desktop application