I'm new to implementing Threads in QT and even after reading the Documentation several times and watching Videos, I get some Error which not even Google can help me with.
thread.cpp:14: error: C2440: "Initialisierung": "QFuture" kann nicht in "QFuture" konvertiert werden
Error Codes are in German, tried to change QT Language, but didn't change the Language of the Errors. I can translate them if needed.
It seems the Error happens in this QFuture<int> future = QtConcurrent::run(&Thread::GenerateTable); command, even thought I wrote it 1:1 like from the QT Documentation.
Here is the Code I want to put in a Thread, as you can see it's writing a bit bunch of Numbers into a File, which takes around a Minute.
Thread.h
#ifndef THREAD_H
#define THREAD_H
#include <QObject>
#include <QFuture>
#include <QtConcurrent/QtConcurrent>
class Thread : public QObject
{
Q_OBJECT
public:
explicit Thread(QObject *parent = nullptr);
static bool start();
private:
int GenerateTable();
};
#endif // THREAD_H
Thread.cpp
#include "thread.h"
Thread::Thread(QObject *parent) : QObject(parent)
{
}
bool Thread::start()
{
QFuture<int> future = QtConcurrent::run(&Thread::GenerateTable);
if (future.result() == 0){
return true;
}
else
return false;
}
int Thread::GenerateTable(){
QString Path = QDir::currentPath();
QFile file(Path + "/Table.csv");
if (!file.open(QFile::WriteOnly | QFile::Text)){
return -1;
}
else{
QTextStream stream(&file);
constexpr uint64_t upper = 10'000'000;
QVector<uint64_t> rando(upper);
std::iota(rando.begin(), rando.end(), 1);
std::shuffle(rando.begin(), rando.end(),
std::mt19937(std::random_device{}()));
for (uint32_t i = 0; i < 10'000'000; ++i) {
stream << rando[i] << ',' << '\n';
}
return 0;
}
}
Thread::GenerateTable() is a member function. It needs an object to work on. You are calling it (er .. passing it to QtConcurrent::run()) from the (static) Thread::start() and there's no Thread object to speak of.
Although you've tagged Qt6, I'll point at the Qt5 documentation for calling member functions: you can pass an object (pointer) which you'll need to allocate from somewhere.
Related
For some application I need to scan WiFi searching for available network (SSID). On Ubuntu 18.04 LTS I don't have any issue with the fallowing code. It return all available SSID as expected but when running on Raspbian stretch (Rasberry PI 3 b) the fallowing code is returning the interface wlan0 and eth0 and not the SSID. Does someone have any clue why? or can tell me what I miss? On the other hand, is it better not to use Qt network lib and use a QProcess and parse what sudo iwlist wlan0 scan is returning?
.cpp
void wificonfig::findavailableWifinetwork( void )
{
QNetworkConfigurationManager ncm;
netconflist = ncm.allConfigurations(QNetworkConfiguration::Discovered); //
int i =0;
awifilist.clear();
for(auto &x : netconflist){
if ((x.bearerType() == QNetworkConfiguration::BearerWLAN) ){
if(x.name() == "")
awifilist << "Unknown(Other Network)";
else{
ui->wificonnection_tw->setItem(i, 0, new QTableWidgetItem(x.name()));
i++;
}
//qDebug() << x.type();
}
}
ui->wificonnection_tw->setRowCount(i);
}
.h
#ifndef WIFICONFIG_H
#define WIFICONFIG_H
#include <QList>
#include <QTimer>
#include <QDialog>
#include <QNetworkConfiguration>
#include <QNetworkConfigurationManager>
#include <QNetworkSession>
namespace Ui {
class wificonfig;
}
class wificonfig : public QDialog
{
Q_OBJECT
public:
explicit wificonfig(QWidget *parent = 0);
~wificonfig();
int connection_count;
QNetworkConfiguration netconf;
QStringList awifilist;
QList<QNetworkConfiguration>netconflist;
public slots:
void findavailableWifinetwork( void );
private slots:
void on_wifi_scan_butt_clicked();
private:
Ui::wificonfig *ui;
QTime *scan_timeout_timer;
QNetworkSession *session;
};
#endif // WIFICONFIG_H
I have looked at Stellarium (software for viewing sky like it is now) code on GitHub for a while. I want to write once soon a program like that, so I started learning C++. I looked at the code and wanted to know what these parts do. And then I asked myself a question: "Where does Stellarium code start?" I want to know in which part of code Stellarium first runs, or in which part of code Stellarium gets a call for running.
P.S.
I am just a beginner in C++. I don't understand it perfectly, so don't be angry at me if I don't know everything and if I missed my question.
Stellarium 'starts' in the 'src' folder, in main.cpp file.
Script:
/*
* Stellarium
* Copyright (C) 2002 Fabien Chereau
* Copyright (C) 2012 Timothy Reaves
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
*/
#include "StelMainView.hpp"
#include "StelSplashScreen.hpp"
#include "StelTranslator.hpp"
#include "StelLogger.hpp"
#include "StelFileMgr.hpp"
#include "CLIProcessor.hpp"
#include "StelIniParser.hpp"
#include "StelUtils.hpp"
#ifndef DISABLE_SCRIPTING
#include "StelScriptOutput.hpp"
#endif
#include <QDebug>
#ifndef USE_QUICKVIEW
#include <QApplication>
#include <QMessageBox>
#include <QStyleFactory>
#else
#include <QGuiApplication>
#endif
#include <QCoreApplication>
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QFontDatabase>
#include <QGuiApplication>
#include <QSettings>
#include <QString>
#include <QStringList>
#include <QTextStream>
#include <QTranslator>
#include <QNetworkDiskCache>
#include <QThread>
#include <clocale>
#ifdef Q_OS_WIN
#include <Windows.h>
//we use WIN32_LEAN_AND_MEAN so this needs to be included
//to use timeBeginPeriod/timeEndPeriod
#include <mmsystem.h>
// Default to High Performance Mode on machines with hybrid graphics
// Details: https://stackoverflow.com/questions/44174859/how-to-give-an-option-to-select-graphics-adapter-in-a-directx-11-application
extern "C"
{
#ifdef _MSC_VER
__declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
__declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 0x00000001;
#else
__attribute__((dllexport)) DWORD NvOptimusEnablement = 0x00000001;
__attribute__((dllexport)) int AmdPowerXpressRequestHighPerformance = 0x00000001;
#endif
}
#else
extern "C"
{
int NvOptimusEnablement = 1;
int AmdPowerXpressRequestHighPerformance = 1;
}
#endif //Q_OS_WIN
//! #class CustomQTranslator
//! Provides custom i18n support.
class CustomQTranslator : public QTranslator
{
using QTranslator::translate;
public:
virtual bool isEmpty() const { return false; }
//! Overrides QTranslator::translate().
//! Calls StelTranslator::qtranslate().
//! #param context Qt context string - IGNORED.
//! #param sourceText the source message.
//! #param comment optional parameter
virtual QString translate(const char *context, const char *sourceText, const char *disambiguation = Q_NULLPTR, int n = -1) const
{
Q_UNUSED(context);
Q_UNUSED(n);
return StelTranslator::globalTranslator->qtranslate(sourceText, disambiguation);
}
};
//! Copies the default configuration file.
//! This function copies the default_cfg.ini file to config.ini (or other
//! name specified on the command line located in the user data directory.
void copyDefaultConfigFile(const QString& newPath)
{
QString defaultConfigFilePath = StelFileMgr::findFile("data/default_cfg.ini");
if (defaultConfigFilePath.isEmpty())
qFatal("ERROR copyDefaultConfigFile failed to locate data/default_cfg.ini. Please check your installation.");
QFile::copy(defaultConfigFilePath, newPath);
if (!StelFileMgr::exists(newPath))
{
qFatal("ERROR copyDefaultConfigFile failed to copy file %s to %s. You could try to copy it by hand.",
qPrintable(defaultConfigFilePath), qPrintable(newPath));
}
QFile::setPermissions(newPath, QFile::permissions(newPath) | QFileDevice::WriteOwner);
}
//! Removes all items from the cache.
void clearCache()
{
QNetworkDiskCache* cacheMgr = new QNetworkDiskCache();
cacheMgr->setCacheDirectory(StelFileMgr::getCacheDir());
cacheMgr->clear(); // Removes all items from the cache.
}
// Main stellarium procedure
int main(int argc, char **argv)
{
Q_INIT_RESOURCE(mainRes);
Q_INIT_RESOURCE(guiRes);
#ifdef Q_OS_WIN
// Fix for the speeding system clock bug on systems that use ACPI
// See http://support.microsoft.com/kb/821893
UINT timerGrain = 1;
if (timeBeginPeriod(timerGrain) == TIMERR_NOCANDO)
{
// If this is too fine a grain, try the lowest value used by a timer
timerGrain = 5;
if (timeBeginPeriod(timerGrain) == TIMERR_NOCANDO)
timerGrain = 0;
}
#endif
// Seed the PRNG
qsrand(QDateTime::currentMSecsSinceEpoch());
QCoreApplication::setApplicationName("stellarium");
QCoreApplication::setApplicationVersion(StelUtils::getApplicationVersion());
QCoreApplication::setOrganizationDomain("stellarium.org");
QCoreApplication::setOrganizationName("stellarium");
// Support high DPI pixmaps and fonts
QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, true);
#if (QT_VERSION>=QT_VERSION_CHECK(5, 6, 0))
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
#endif
#if defined(Q_OS_MAC)
QFileInfo appInfo(QString::fromUtf8(argv[0]));
QDir appDir(appInfo.absolutePath());
appDir.cdUp();
QCoreApplication::addLibraryPath(appDir.absoluteFilePath("PlugIns"));
#elif defined(Q_OS_WIN)
QFileInfo appInfo(QString::fromUtf8(argv[0]));
QCoreApplication::addLibraryPath(appInfo.absolutePath());
#endif
QGuiApplication::setDesktopSettingsAware(false);
#ifndef USE_QUICKVIEW
QApplication::setStyle(QStyleFactory::create("Fusion"));
// The QApplication MUST be created before the StelFileMgr is initialized.
QApplication app(argc, argv);
#else
QGuiApplication::setDesktopSettingsAware(false);
QGuiApplication app(argc, argv);
#endif
// QApplication sets current locale, but
// we need scanf()/printf() and friends to always work in the C locale,
// otherwise configuration/INI file parsing will be erroneous.
setlocale(LC_NUMERIC, "C");
// Solution for bug: https://bugs.launchpad.net/stellarium/+bug/1498616
qputenv("QT_HARFBUZZ", "old");
// Init the file manager
StelFileMgr::init();
SplashScreen::present();
// Log command line arguments.
QString argStr;
QStringList argList;
for (int i=0; i<argc; ++i)
{
argList << argv[i];
argStr += QString("%1 ").arg(argv[i]);
}
// add contents of STEL_OPTS environment variable.
QString envStelOpts(qgetenv("STEL_OPTS").constData());
if (envStelOpts.length()>0)
{
argList+= envStelOpts.split(" ");
argStr += " " + envStelOpts;
}
//save the modified arg list as an app property for later use
qApp->setProperty("stelCommandLine", argList);
// Parse for first set of CLI arguments - stuff we want to process before other
// output, such as --help and --version
CLIProcessor::parseCLIArgsPreConfig(argList);
#ifdef Q_OS_WIN
if (qApp->property("onetime_angle_mode").isValid())
{
app.setAttribute(Qt::AA_UseOpenGLES, true);
}
if (qApp->property("onetime_mesa_mode").isValid())
{
app.setAttribute(Qt::AA_UseSoftwareOpenGL, true);
}
#endif
// Start logging.
StelLogger::init(StelFileMgr::getUserDir()+"/log.txt");
StelLogger::writeLog(argStr);
// OK we start the full program.
// Print the console splash and get on with loading the program
QString versionLine = QString("This is %1 - %2").arg(StelUtils::getApplicationName()).arg(STELLARIUM_URL);
QString copyrightLine = QString("Copyright (C) %1 Fabien Chereau et al.").arg(COPYRIGHT_YEARS);
int maxLength = qMax(versionLine.size(), copyrightLine.size());
qDebug() << qPrintable(QString(" %1").arg(QString().fill('-', maxLength+2)));
qDebug() << qPrintable(QString("[ %1 ]").arg(versionLine.leftJustified(maxLength, ' ')));
qDebug() << qPrintable(QString("[ %1 ]").arg(copyrightLine.leftJustified(maxLength, ' ')));
qDebug() << qPrintable(QString(" %1").arg(QString().fill('-', maxLength+2)));
qDebug() << "Writing log file to:" << QDir::toNativeSeparators(StelLogger::getLogFileName());
qDebug() << "File search paths:";
int n=0;
for (const auto& i : StelFileMgr::getSearchPaths())
{
qDebug() << " " << n << ". " << QDir::toNativeSeparators(i);
++n;
}
// Now manage the loading of the proper config file
QString configName;
try
{
configName = CLIProcessor::argsGetOptionWithArg(argList, "-c", "--config-file", "config.ini").toString();
}
catch (std::runtime_error& e)
{
qWarning() << "WARNING: while looking for --config-file option: " << e.what() << ". Using \"config.ini\"";
configName = "config.ini";
}
QString configFileFullPath = StelFileMgr::findFile(configName, StelFileMgr::Flags(StelFileMgr::Writable|StelFileMgr::File));
if (configFileFullPath.isEmpty())
{
configFileFullPath = StelFileMgr::findFile(configName, StelFileMgr::New);
if (configFileFullPath.isEmpty())
qFatal("Could not create configuration file %s.", qPrintable(configName));
}
QSettings* confSettings = Q_NULLPTR;
if (StelFileMgr::exists(configFileFullPath))
{
confSettings = new QSettings(configFileFullPath, StelIniFormat, Q_NULLPTR);
// Implement "restore default settings" feature.
bool restoreDefaultConfigFile = false;
if (CLIProcessor::argsGetOption(argList, "", "--restore-defaults"))
restoreDefaultConfigFile=true;
else
restoreDefaultConfigFile = confSettings->value("main/restore_defaults", false).toBool();
if (!restoreDefaultConfigFile)
{
QString version = confSettings->value("main/version", "0.0.0").toString();
if (version!=QString(PACKAGE_VERSION))
{
QTextStream istr(&version);
char tmp;
int v1=0;
int v2=0;
istr >> v1 >> tmp >> v2;
// Config versions less than 0.6.0 are not supported, otherwise we will try to use it
if (v1==0 && v2<6)
{
// The config file is too old to try an importation
qDebug() << "The current config file is from a version too old for parameters to be imported ("
<< (version.isEmpty() ? "<0.6.0" : version) << ").\n"
<< "It will be replaced by the default config file.";
restoreDefaultConfigFile = true;
}
else
{
qDebug() << "Attempting to use an existing older config file.";
confSettings->setValue("main/version", QString(PACKAGE_VERSION)); // Upgrade version of config.ini
clearCache();
qDebug() << "Clear cache and update config.ini...";
}
}
}
if (restoreDefaultConfigFile)
{
if (confSettings)
delete confSettings;
QString backupFile(configFileFullPath.left(configFileFullPath.length()-3) + QString("old"));
if (QFileInfo(backupFile).exists())
QFile(backupFile).remove();
QFile(configFileFullPath).rename(backupFile);
copyDefaultConfigFile(configFileFullPath);
confSettings = new QSettings(configFileFullPath, StelIniFormat);
qWarning() << "Resetting defaults config file. Previous config file was backed up in " << QDir::toNativeSeparators(backupFile);
clearCache();
}
}
else
{
qDebug() << "Config file " << QDir::toNativeSeparators(configFileFullPath) << " does not exist. Copying the default file.";
copyDefaultConfigFile(configFileFullPath);
confSettings = new QSettings(configFileFullPath, StelIniFormat);
}
Q_ASSERT(confSettings);
qDebug() << "Config file is: " << QDir::toNativeSeparators(configFileFullPath);
#ifndef DISABLE_SCRIPTING
QString outputFile = StelFileMgr::getUserDir()+"/output.txt";
if (confSettings->value("main/use_separate_output_file", false).toBool())
outputFile = StelFileMgr::getUserDir()+"/output-"+QDateTime::currentDateTime().toString("yyyyMMdd-HHmmss")+".txt";
StelScriptOutput::init(outputFile);
#endif
// Override config file values from CLI.
CLIProcessor::parseCLIArgsPostConfig(argList, confSettings);
// Add the DejaVu font that we use everywhere in the program
const QString& fName = StelFileMgr::findFile("data/DejaVuSans.ttf");
if (!fName.isEmpty())
QFontDatabase::addApplicationFont(fName);
QString fileFont = confSettings->value("gui/base_font_file", "").toString();
if (!fileFont.isEmpty())
{
const QString& afName = StelFileMgr::findFile(QString("data/%1").arg(fileFont));
if (!afName.isEmpty() && !afName.contains("file not found"))
QFontDatabase::addApplicationFont(afName);
else
qWarning() << "ERROR while loading custom font " << QDir::toNativeSeparators(fileFont);
}
// Set the default application font and font size.
// Note that style sheet will possibly override this setting.
#ifdef Q_OS_WIN
// Let's try avoid ugly font rendering on Windows.
// Details: https://sourceforge.net/p/stellarium/discussion/278769/thread/810a1e5c/
QString baseFont = confSettings->value("gui/base_font_name", "Verdana").toString();
QFont tmpFont(baseFont);
tmpFont.setStyleHint(QFont::AnyStyle, QFont::OpenGLCompatible);
#else
QString baseFont = confSettings->value("gui/base_font_name", "DejaVu Sans").toString();
QFont tmpFont(baseFont);
#endif
tmpFont.setPixelSize(confSettings->value("gui/gui_font_size", 13).toInt());
QGuiApplication::setFont(tmpFont);
// Initialize translator feature
StelTranslator::init(StelFileMgr::getInstallationDir() + "/data/iso639-1.utf8");
// Use our custom translator for Qt translations as well
CustomQTranslator trans;
app.installTranslator(&trans);
StelMainView mainWin(confSettings);
mainWin.show();
SplashScreen::finish(&mainWin);
app.exec();
mainWin.deinit();
delete confSettings;
StelLogger::deinit();
#ifdef Q_OS_WIN
if(timerGrain)
timeEndPeriod(timerGrain);
#endif //Q_OS_WIN
return 0;
}
Thanks for all effort.
P.S.
I know that question was very unclear, but I couldn't do it better.
I am using Qt on my RPI3.
I found a QML example which is Tesla Car instrument cluster. You can access full code from here or here.
I successfully created a project and debugged it. Now I am trying to change a value in the QML code from C++ side. There is a timer in my C++ code every 30 seconds I am trying to change speed value in the QML code with using QMetaObject::inokeMethod(): function. I read all examples in here.
Here is my C ++ code
#ifndef MYTIMER_H
#define MYTIMER_H
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlComponent>
#include <QTimer>
#include <QtDebug>
class MyTimer : public QObject
{
Q_OBJECT
public:
MyTimer();
QTimer *timer;
int i=0;
public slots:
void MySlot();
};
#endif // MYTIMER_H
#include "mytimer.h"
MyTimer::MyTimer()
{
timer = new QTimer(this);
connect(timer,SIGNAL(timeout()),this,SLOT(MySlot()));
timer->start(10000);
}
void MyTimer::MySlot()
{
i++;
if(i==3)
{
i=0;
QQmlEngine engine;
QQmlComponent component(&engine,QUrl(QStringLiteral("qrc:/Speedometer.qml")));
QObject *object = component.create();
QVariant speeds=100;
QVariant returnedValue;
QMetaObject::invokeMethod(object,"speedNeedleValue",
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant, speeds));
qDebug() << "From QML"<< returnedValue.toString();
delete object;
}
}
Here is QML code:
import QtQuick 2.4
import QtGraphicalEffects 1.0
Rectangle {
color: "transparent"
SpeedNeedle {
id: speedoNeedle
anchors.verticalCenterOffset: 0
anchors.centerIn: parent
focus: true
Keys.onPressed: {
if (event.key == Qt.Key_A) {
speedNeedleValue(100)
drive()
}
}
function speedNeedleValue(speeds) {
speedoNeedle.value = speeds
return ": I am here"
}
}
If I press the "A" button my speedNeedleValue(); function is working. And in debug page I can get the return data return ": I am here".
Problem is I can't set the speeds argument with invoke function.
Here is the debug page:
"https://preview.ibb.co/kqpvWS/rpi.png"
Every time interrupt I can get "I am here". but I also get " JIT is disabled.... " warning too.
Thank you for your answers.
I'm trying call a Qt Mainwindow function in my main function but unfortunately it does not work
some info: I've written a simple log in application. here's the code for it:
void MainWindow::on_pushButton_Login_clicked()
{
QString username = ui->lineEdit_username->text();
QString password = ui->lineEdit_password->text();
if(username == "test" && password == "test")
{
QMessageBox::information(this,"Login", "Username and password is
correct");
}
else
{
QMessageBox::warning(this,"Login", "Username and Password is not
correct");
}
}
I also have a piece of code for saving the content of a batch file into a vector.
and in that code I have a find function, to look for a certain word.
what I'm trying to achieve here exactly is 1.save the contents of the batch to my vector, then have the find function look for that certain word in that vector and then when this word is found, prompt the user to enter username and password (which is done through my log in application)
Now here's where my problem is, I have all the code, separately but I don't know how to put it together, I'm not a c++ programmer, in fact I'm a complete noob. my boss just asked me to get this done, and I'm struggling :c
Here's the code for populating my vector with the contents of the batch file
int main()
{
// VARIABLES
// file path, pointer
const char * filePath = "C:/Users/Name/Downloads/test.bat";
// single line
std::string line;
// vector
std::vector<std::string> my_vec;
// filestream, reading
//std::ifstream myfile("batch.bat");
std::ifstream myfile(filePath);
// Test to open file
if (!myfile)
{
std::cout << "Error opening file" << std::endl;
exit(1);
}
else
{
std::cout << "File opened successfully (for reading)" << std::endl;
}
// Read from file and put into vector
while (myfile) // while we are reading the file
{
getline(myfile, line);
my_vec.push_back(line);
}
//my find function
std::vector<std::string>::iterator i;
i = std::find(my_vec.begin(),my_vec.end(),"batch");
if (i != my_vec.end())
/**** here is where id like to call my clicked function ****/
/* tried putting in "void MainWindow::on_pushButton_Login_clicked()" but it
here's what I got */
1. error: undefined reference to `qMain(int, char**)'
and collect2.exe:-1: error: error: ld returned 1 exit status
else
std::cout<<"No result found" << std::endl;
// Close filestream
myfile.close();
return 0;
}
I truly apologize if this is too specific or an extremely dumb question, but I just needed help and I couldn't find anything on such a specific question, also everything that could help, is for people who actually know what they're doing with c++
I'd appreciate any contribution!
Bearded beaver: My MainWindow class is defined in my mainwindow.H header file
which I included in my main.cpp file
heres the code in that Mainwindow.h file
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void on_pushButton_Login_clicked();
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
and here is what I entered in my Find function from above
std::vector<std::string>::iterator i;
i = std::find(my_vec.begin(),my_vec.end(),"much");
if (i != my_vec.end())
MainWindow.on_pushButton_Login_clicked();
else
std::cout<<"No result found" << std::endl;
and this is the error that I get
main.cpp:101: error: expected unqualified-id before '.' token
MainWindow.on_pushButton_Login_clicked();
^
thanks for taking the time!
I basically did something really stupid by altering the main.cpp file (in Qt Widgets application) and removing the default main function which looked like this
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
In that the object name was declared, I needed it to to call my function which was in that MainWindow class. like so:
w.on_pushButton_Login_clicked();
unfortunately though, my find function does not work.
I wanted to have a conditional statement that calls upon my function if a certain string element in my vector is found using:
if (std::find(my_vec.begin(),my_vec.end(),much) != my_vec.end() ) //or "much"
w.on_pushButton_Login_clicked();
else
std::cout<<"No result found" << std::endl;
I get no errors, it just prompts me to the log in application regardless of if element was found.
I don't know why this happens, but if I found out, I will edit this answer ^^ thank you guys for taking the time, apologize in advance if i used wrong terminology/wording.
I have been all day long googling for a solution and changing my code, but no luck.
Basically, I have added translation to my app. It is working fine except here:
QString MainWindow::getMessage(Messages msg) {
static const char* const messages[] = {
QT_TR_NOOP("Setting power on"),
QT_TR_NOOP("Reading ID..."),
QT_TR_NOOP("Programming..."),
QT_TR_NOOP("Setting write-protect"),
QT_TR_NOOP("Finished ok"),
QT_TR_NOOP("PROGRAMMED OK"),
QT_TR_NOOP("ERROR!"),
QT_TR_NOOP("OK"),
QT_TR_NOOP("The programmer is not connected.\nPlease check the connection."),
QT_TR_NOOP("Disconnect the board, it is in short!!"),
QT_TR_NOOP("ERROR: Supply voltage too low (1 Volt is required, Measured: 0.0 Volt)."),
QT_TR_NOOP("Board is already programmed and write protected."),
QT_TR_NOOP("Check device connection or there is short."),
QT_TR_NOOP("Unknown error.")
};
return tr(messages[msg]);
}
However, I don't get the translation. The files for translation seems to be ok, the UI translations are applied fine.
I also tried this:
static const char* const messages[] = {
QT_TRANSLATE_NOOP("test", "Setting power on"),
QT_TRANSLATE_NOOP("test", "Reading ID..."),
QT_TRANSLATE_NOOP("test", "Programming..."),
QT_TRANSLATE_NOOP("test", "Setting write-protect"),
QT_TRANSLATE_NOOP("test", "Finished ok"),
QT_TRANSLATE_NOOP("test", "PROGRAMMED OK"),
QT_TRANSLATE_NOOP("test", "ERROR!"),
QT_TRANSLATE_NOOP("test", "OK"),
QT_TRANSLATE_NOOP("test", "The programmer is not connected.\nPlease check the connection."),
QT_TRANSLATE_NOOP("test", "Disconnect the board, it is in short!!"),
QT_TRANSLATE_NOOP("test", "ERROR: Supply voltage too low (1 Volt is required, Measured: 0.0 Volt)."),
QT_TRANSLATE_NOOP("test", "Board is already programmed and write protected."),
QT_TRANSLATE_NOOP("test", "Check device connection or there is short."),
QT_TRANSLATE_NOOP("test", "Unknown error.")
};
Then, I have a method to get the message:
QString MainWindow::getMessage(Messages msg) {
return qApp->translate("test", messages[msg]);
}
But it doesn't work either.
Any tips or suggestions?
I have found the real issue here.
Usually translators are installed at main.cpp, so the translator object remains in memory.
However, in my case, I was switching the translator after the user changes the language at settings dialog, using a local variable but void QCoreApplication::installTranslator ( QTranslator * translationFile ) [static] needs a pointer. That local variable is removed as soon as the function exits.
So, I declared a QTranslator object on my class, so it keeps in memory.
Maybe not applicable in this situation, but often people forget to place the Q_OBJECT macro in the class declaration. Resulting in (amongst others) tr() not working.
I was preparing a simpler source to upload here but now it is working fine! I rebooted my PC yesterday, you know, sometimes a reboot fixes everything (?).
Anyway, here is some source as it was requested. And by the way, I'm doing the translation on the fly, and by letting the user to choose the language (not by detecting locales):
This is main.cpp (nothing was added by me):
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
This is mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDir>
#include <QTranslator>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QDir d(":/translations/");
QStringList files = d.entryList(QStringList("*.qm"));
qDebug("There are %d files for translation", files.count());
// Now let's fill the combobox
this->ui->comboBox->clear();
for (int i = 0; i < files.count(); ++i) {
QTranslator translator;
translator.load(files[i], ":/translations/");
QString language = translator.translate("MainWindow",
"English");
this->ui->comboBox->addItem(language);
}
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_comboBox_currentIndexChanged(int index)
{
// Now, based on the new itemindex, let's change the translator
QString selectedLang = this->ui->comboBox->itemText(index);
QString language;
QDir d(":/translations/");
QStringList files = d.entryList(QStringList("*.qm"));
for (int i = 0; i < files.count(); ++i) {
QTranslator translator;
translator.load(files[i], ":/translations/");
language = translator.translate("MainWindow",
"English");
if (language == selectedLang) {
if (!qApp->installTranslator(&translator)) {
qDebug("ERROR INSTALLING TRANSLATOR !!!");
}
this->uiTranslate();
break;
}
}
}
/// This function translates all the UI texts:
void MainWindow::uiTranslate(void) {
this->setWindowTitle(tr("MainWindow"));
// Just for testing, also show all the messages
for (int i = 0; i < MSG_LAST; ++i) {
this->ui->textBrowser->append(this->getMessage((Messages)i));
}
}
QString MainWindow::getMessage(Messages idx) {
static const char* const messagesText[MSG_LAST] = {
QT_TR_NOOP("Hello!"),
QT_TR_NOOP("Bye bye"),
QT_TR_NOOP("Nice to meet you")
};
return (tr(messagesText[idx]));
}
in this test app, the UI just has a combobox and a text browser.
The combobox is filled with the languages included on the resource file.
When I change the combobox, the mainwindow title is changed and the messages are printed in the right language.
Thanks anyway!
Best regards,