Check if QAction is initialized - qt

I have in my header file the definition:
QAction actionPlay;
In my cpp file I have a function:
myFunc()
{
actionPlay = new QAction();
}
I want to make a change in my UI only the first time I enter the function myFunc().
I thought about checking if actionPlay has been initialized or not (if we have already called the line actionPlay = new QAction(); )
How can I do this ?
Thanks

The line:
actionPlay = new QAction()
is attempting to assign a pointer to a non pointer variable declared in
QAction actionPlay
so wont works as is.
If you changed the code to:
QAction * actionPlay = 0;
It would work, and you could then check if it was initialized:
if(!actionPlay) actionPlay = new QAction();

If you want to init action for every object:
QACtion *actionPay = nullptr; // *.h file
if(!actionPay) { actionPay = new QAction(); ..... } // *.cpp file
or don't use pointer
if(!actionPay.isEnabled()) { ... enable actionPay ...} // *.cpp file
if you want do one action:
//in your function *.cpp file
static bool once = true;
if(once) {
once = false;
... some code executed in the first call ...
}

Related

How to link signal and slot when i change the font in the dialog

This is how i am currently choosing the font in my application.
void FontChange()
{
QString filePath = QFileDialog::getOpenFileName(NULL, tr("Open File"),
QStandardPaths::standardLocations(QStandardPaths::FontsLocation)[0],
tr("Fonts (*.ttf);;Everything (*.*)"), nullptr,
QFileDialog::DontUseNativeDialog);
if (filePath.isEmpty())
return;
QlineEditSetFont->setText(filePath);
stdstrLocation = filePath.toStdString();
this->isChanged = true; // this executes the function
}
I want to execute a function whenever i change my selection in the Dialog , currently i have to choose a font and than click on open to execute the function
////////////////////////////////////////////////////////////////////////////
Now i am using a non modal way but how can i determine if cancel has been pressed.
Further Edit
QFileDialog* dialog = new QFileDialog();
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setNameFilter("TTF (*.ttf)");
dialog->setOption(QFileDialog::DontUseNativeDialog);
dialog->setDirectory("C:\\Windows\\Fonts");
QObject::connect(dialog, &QFileDialog::currentChanged, [=](const QString &path) {
qDebug() << path; stdstrLocation = path.toStdString(); this->isChanged = true;
QStringList fileNames = dialog->selectedFiles();
qDebug() << "Selected FIles" << fileNames.size();
});
dialog->show();
You can't use the static convenience method but need to create the QFileDialog instance manually:
auto dialog = new QFileDialog(someParent);
dialog->setWindowTitle(tr("Open File"));
dialog->setDirectory(QStandardPaths::standardLocations(QStandardPaths::FontsLocation)[0]);
dialog->setNameFilter(tr("Fonts (*.ttf);;Everything (*.*)"));
// more setup...
connect(dialog, &QFileDialog::filesSelected, this, [this](const QStringList &selected) {
// handle selection change here
});
if (dialog->exec() == QDialog::Accepted) { // alternatively use open() to avoid blocking exec()
// do something with dialog->selectedFiles()...
}
delete dialog;
Actually, those are two different questions. The one from the title has been already answered. The answer to the second one, namely How can i determine if cancel has been pressed, lies in the documentation of QFileDialog::getOpenFileName itself:
If the user presses Cancel, it returns a null string.
With this in mind, you can do something like:
void FontChange()
{
QString filePath = QFileDialog::getOpenFileName(NULL, tr("Open File"),
QStandardPaths::standardLocations(QStandardPaths::FontsLocation)[0],
tr("Fonts (*.ttf);;Everything (*.*)"), nullptr,
QFileDialog::DontUseNativeDialog);
if (filePath.isNull()) {
// user pressed Cancel
} else if (filePath.isEmpty()) {
return;
} else {
QlineEditSetFont->setText(filePath);
stdstrLocation = filePath.toStdString();
this->isChanged = true; // this executes the function
}
}
You can of course rewrite the if part to be more suitable to your app's logic.
As a side note, QString::isEmpty also implies that it is NULL.

Qt -how to get variable value from another function in same file

New to Qt. Still learning it. I have clone.ui, clone.h and clone.cpp. clone ui has 2 buttons.
Browse button-> to Selection a destination path
Add button -> Clone(copy) a file
Clone.h
QString destination_path;
QFileDialog *fdialog;
Clone.cpp has
QFileInfo finfo; // Declare outside function to increase scope
QString destination_name;
void Clone:: on_pushButton__Browse_clicked()
{
/*get the destination path in QString using QFileDialog
Got destination_path */
QString destinatino_path = QFileDialog::getExistingDirectory(....);
QFile finfo(destination_path);
// QFileDialog finfo(destionation_path)
}`
In the same file Clone.cpp
void Clone:: on_btn_Add_clicked()
{
// how to get the same destination_path value here...
//using QFile or some other way?
}
I struck here, Am i missing anything? Any thoughts/suggestion highly useful.
You've create a class (Clone) which has a data member QString destination_path.
Since it is a member variable it has class scope (as in you can access the same variable in any Clone:: member function for the same Clone object).
The problem is that you've hidden it by declaring another QString destination_path in Clone::on_pushButton__Browse_clicked().
void Clone::on_pushButton__Browse_clicked()
{
...
// this *hides* the class member with the same name
QString destination_path = QFileDialog::getExistingDirectory(....);
...
}
The solution is to remove QString from the beginning of the line, which means you are now assigning to the class object's data member.
void Clone::on_pushButton__Browse_clicked()
{
...
// now you're assigning to your object's data member
destination_path = QFileDialog::getExistingDirectory(....);
...
}
Later, in Clone::on_btn_Add_clicked() you can access destination_path, and it will have the value assigned to it in Clone::on_pushButton__Browse_clicked

How to use QDBusPendingCallWatcher properly?

I'm trying to use QDBusPendingCallWatcher to watch an async call. Some sample code like this:
{
// interface = new QDBusInterface(...);
QDBusPendingCall pcall = interface->asyncCall("query");
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pcall, this);
QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(handler(QDBusPendingCallWatcher*)));
}
and handler function:
void Client::handler(QDBusPendingCallWatcher* call)
{
QDBusPendingReply<QString> reply = *call;
// do something
}
My questions are:
It looks like QDBusPendingCallWatcher uses shared data pointer inside, is it safe to not manually delete the watcher pointer? Just leave the scope and forget it?
If I can let the smart pointer of pendingcall to do all the tricks, can I use just one QDBusPendingCallWatcher pointer in my class to watch all the async calls? Like this:
{
QDBusPendingCall pcall = interface->asyncCall("query");
watcher = new QDBusPendingCallWatcher(pcall, this);
QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(handleOne(QDBusPendingCallWatcher*)));
pcall = interface->asyncCall("anotherQuery");
watcher = new QDBusPendingCallWatcher(pcall, this);
QObject::connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(handleTwo(QDBusPendingCallWatcher*)));
}
Will this makes a disaster? Or should I use multiple pointers for each call?
Thanks!
Take a closer look at the QDBusPendingCallWatcher documentation:
The slot connected to by the above code could be something similar to the following:
void MyClass::callFinishedSlot(QDBusPendingCallWatcher *call)
{
QDBusPendingReply<QString, QByteArray> reply = *call;
if (reply.isError()) {
showError();
} else {
QString text = reply.argumentAt<0>();
QByteArray data = reply.argumentAt<1>();
showReply(text, data);
}
call->deleteLater();
}
The call of QObject::deleteLater is the key: This means Qt will delete the Object as soon as execution returns to the event loop.
As long as you call deleteLater inside Client::handler(...), you don't need to - more precisely you musn't - call delete watcher; anywhere. The only thing you have to ensure is that noone uses the object behind call after the slot returns.

Save (already-existing) QSetting into an INI file

I want to save an alredy-existing QSettings object into some INI file for backup.
The QSettings comes from the application's global settings, ie. it can be registry, ini file, etc.
In case it helps, my context is:
class Params
{
// All params as data members
// ...
void loadGlobal ()
{
Qettings s; // Global parameters, paths set by application
// Fill data members: s.value (...);
}
};
class Algo
{
Result run (Params p)
{
Result r = F(p);
return r;
}
};
int main (...)
{
Params p;
p.loadGlobal ();
Algo a;
Result r = a.run (p);
// At this point, save Result and Params into a specific directory
// Is there a way to do:
p.saveToIni ("myparams.ini"); // <-- WRONG
}
A solution would be to add a saveTo (QSetting & s) method into the Params class:
class Params
{
void saveTo (QSettings & s)
{
s.setValue (...);
}
};
int main (...)
{
Params p;
p.loadGlobal ();
QSettings bak ("myparams.ini", ...);
p.saveTo (bak);
}
But I am looking for a solution without modifying the Params class.
Well, no, QT Doesn't really support this directly. I think your best bet is writing a helper class...something like:
void copySettings( QSettings &dst, QSettings &src )
{
QStringList keys = src.allKeys();
for( QStringList::iterator i = keys.begin(); i != keys.end(); i++ )
{
dst.setValue( *i, src.value( *i ) );
}
}
I think there are 2 issues:
QSettings does not have a copy constructor or assignment operator (that I know of), so you'll probably have to write your own copy using allKeys().
You can't save QSettings to an arbitrary file, but what you can do is set the path used for a specific format and scope using the static method QSettings::setPath(). Note that you need to do that before your backup QSettings object is created (and you would use format IniFormat).
If you're OK not having complete control over the resulting path, this should be sufficient. If not, you could still do the above, then get the file name using fileName() and use a system call to copy/move the file to the desired final location.

How can I replace class_createInstance in arc?

I have this code and need to port it to arc but I dont know how:
case FIELDTYPE_OBJECT:
className = [fieldType substringWithRange:NSMakeRange(2, [fieldType length]-3)];
rel = class_createInstance(NSClassFromString(className), sizeof(unsigned));
Class theClass = [rel class];
if ([rel isKindOfClass:[DbObject class]]) {
//Load the record...
NSInteger Id = [rs intForColumn:[theClass relationName]];
if (Id==0) {
fieldValue = [rel init];
} else {
Db *db = [Db currentDb];
fieldValue = [db loadById: theClass theId:Id];
}
}
break;
The error is:
error: 'class_createInstance' is unavailable: not available in automatic reference counting mode
How replace it?
I need to build class objects in runtime.
The most straightforward solution is to add another file which has -fno-objc-arc set on it, and which has a function which calls class_createInstance() as above.
Try this:
#include <objc/objc-runtime.h>
id object = [[NSClassFromString(#"TheClassName") alloc] init];
Create a separated .h/.c files and put something like this.
id const
MyCreateInstanceOfClass(Class const class)
{
id instance = class_createInstance(class, 0);
return instance;
}
#include the .h, and call it. No need to put -fno-bjc-arc switch for each file.

Resources