What to do with .h file generated using .ui file? - c++

I used QT Desginer to create a finalversion_with_buttons.ui file,
later i converted it to finalversion_with_buttons.h file using the command
uic -o finalversion_with_buttons.h finalversion_with_buttons.ui
in command prompt.
I got to know that we cannot have a .cpp file and .h file contains everything we need, now how do i execute/run this .h file ?

Please check Qt Creator documentation e.g. "Creating a Qt Widget Based Application". It will give you some overview how to setup qmake/CMake project based on UI form files (aka Qt Widgets). The UI files itself may not be used standalone. It is only UI description.

It is always of benefit to create a ".pro" or ".cmake" file that contails all the stuff for the compilation of the project that has several benefits, even for
small programms.
I highly suggest reading through this sites, that helped me a lot in creating/compiling projects:
https://www.cprogramming.com/tutorial/makefiles.html
https://www.cprogramming.com/tutorial/makefiles_continued.html
This is what an automatic generated .pro file of the qt creator contains and I guess self explainatory:
QT += core gui multimedia multimediawidgets
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
RESOURCES += \
mainwindow.qrc
If you are working with the qt designer part of the qt creator you got this xml .ui file and the easiest way to compile it would be just clicking on Build->Run or ctrl+R. If your .pro file looks like the above example with the right file names you should be good to go.
Actually it is possible to have just a c++ file and no header files - thats invented to make the projects more modular with classes - thats what c++ is all about compared with c. To quote Bjarne "Classes use to hide the ugly stuff" ..so you can read the programm and understand it without even knowing what the class files contain and do with your code with a proper reference, and you don't should have to care. And thats what qt does - hiding the ugly stuff you would have to do all by yourself in its classes so you can just call QPushButton and it works. (and many more benefits but to keep it simple, qt is just c++ classes)
This is an example for a class in the code without a header file:
[//example from here https://www.cprogramming.com/tutorial/lesson12.html][1]
#include <iostream>
using namespace std;
class Computer // Standard way of defining the class
{
public:
// This means that all of the functions below this(and any variables)
// are accessible to the rest of the program.
// NOTE: That is a colon, NOT a semicolon...
Computer();
// Constructor
~Computer();
// Destructor
void setspeed ( int p );
int readspeed();
protected:
// This means that all the variables under this, until a new type of
// restriction is placed, will only be accessible to other functions in the
// class. NOTE: That is a colon, NOT a semicolon...
int processorspeed;
};
// Do Not forget the trailing semi-colon
Computer::Computer()
{
//Constructors can accept arguments, but this one does not
processorspeed = 0;
}
Computer::~Computer()
{
//Destructors do not accept arguments
}
void Computer::setspeed ( int p )
{
// To define a function outside put the name of the class
// after the return type and then two colons, and then the name
// of the function.
processorspeed = p;
}
int Computer::readspeed()
{
// The two colons simply tell the compiler that the function is part
// of the class
return processorspeed;
}
int main()
{
Computer compute;
// To create an 'instance' of the class, simply treat it like you would
// a structure. (An instance is simply when you create an actual object
// from the class, as opposed to having the definition of the class)
compute.setspeed ( 100 );
// To call functions in the class, you put the name of the instance,
// a period, and then the function name.
cout<< compute.readspeed();
// See above note.
}
And a compiler doesn't see something else after the linker is done than that.
so
"I got to know that we cannot have a .cpp file and .h file contains
everything we need"
is not right because you can as seen in the example above. Just its not how c++ (or c with classes as it was called in the early days) should be used.
But to answer your question:
"how do i execute/run this .h file ?"
like said before, just use the qt creator and click on Run or crtl + R
(it is free for opensource and edu)
create a project file like exampled before and use qmake SampleProject.pro
in the command line. This will create a file by the name of “Makefile” in the project directory.
(like described here https://vitux.com/compiling-your-first-qt-program-in-ubuntu/
than issue the command make in the same directory
(also described here)
Create a make file like described in link 1 and 2.
Everything else is beyond the scope of this question like fiddling out the semantic for using gcc or g++
That being said, you can create QPushButtons and all the stuff with the qt creator or you can create push buttons just in the code without using the .ui xml - file
like described here:
https://www.bogotobogo.com/Qt/Qt5_LayoutNotUsingDesigner.php
But what all of the guys here highly suggest is: Get yourself a goot qt/c++ book or tutorial and learn the foundations about classes and qt and you gonna get to be a really good programmer in no time. I also hope deeply this post is able to clarify a lot of qt programming/compiling for you and you start to have fun and will create really nice applications :) Cheers

Related

Call a method or function from Objective-c in AppleScript

I'm trying to use LestMove to be more precise
the second implementation method where it says:
Option 2:
Copy the following files into your project:
PFMoveApplication.h
PFMoveApplication.m
If your project has ARC enabled, you'll want to disable ARC on the above files. You can do so by adding -fno-objc-arc compiler flag to your PFMoveApplication.m source file. See How can I disable ARC for a single file in a project?
If your application is localized, also copy the 'MoveApplication.string' files into your project.
Link your application against Security.framework.
In your app delegate's "-[applicationWillFinishLaunching:]" method, call the PFMoveToApplicationsFolderIfNecessary function at the very top.
but I'm not able to call the method / Class, could someone help me with this issue? Thanks in advance!
In general, there are a couple of ways to set up an Objective-C class in your AppleScriptObjC project:
Add the file(s) to the project - the Objective-C class name will be
the one used in the #interface/#implementation declarations
Add an outlet property in the AppleScript class/script you are using, e.g. property someProperty : missing value
Instantiate the class programmatically:
set someProperty to current application's ClassName's alloc's init()
or
Connect stuff up with the Interface Builder:
Add an NSObject (blue cube) from the library to your project
Set the class of the object/cube to the class name of the Objective-C file(s) in the Identity Inspector
Connect the AppDelegate IB Outlet to the object/cube in the Connections Inspector
After setting up the outlet property, the Objective-C methods can be used like any other script/class:
someProperty's handler()
That LetsMove project wasn't really set up for AppleScriptObjC, but I was able to tweak it a bit to get it running. I'm not that great at writing Objective-C, but the following worked for me using a new default AppleScript project with Xcode 10 in Mojave (the original file is over 500 lines long, so I'm just highlighting the changes):
Add PFMoveApplication.h and PFMoveApplication.m files to the project (the class name is LetsMove)
Add Security.framework to Link Binary With Libraries in Build Phases
As described in the original project README, add the compiler flag -fno-objc-arc to the Objective-C file in Compile Sources of the Build Phases
-- Now to alter the Objective-C files a bit:
Move the #interface declaration to the .h file and include the redefined method signatures below in it:
The PFMoveToApplicationsFolderIfNecessary and PFMoveIsInProgress methods are redefined as instance methods:
- (void)PFMoveToApplicationsFolderIfNecessary;
- (BOOL)PFMoveIsInProgress;
Redefine the above method signatures in the .m file, and include those methods in the #implementation section - to do this, move the #end to just before the helper methods (after the PFMoveIsInProgress method)
Remove the isMainThread statement at the beginning of the PFMoveToApplicationsFolderIfNecessary method - this is not not needed (AppleScript normally runs on the main thread), and fixes another issue
There is still a little stuff in there from the original app such as NSUserDefaults, so for your own project, give it a look to see if anything else needs changing (dialog text, etc)
And finally, in the AppDelegate.applescipt file, the following was added to applicationWillFinishLaunching:
current application's LetsMove's alloc's init()'s PFMoveToApplicationsFolderIfNecessary()

Embedding localized satellite dll into exe application

I have a C++ CLR/CLI project, I wonder how to embed a localized satellite dll into my exe application, I found similar solutions but it's for C# projects which is pretty different from my project structure.
Is it possible to embed it directly into the binary?
By the way I'm getting issues with namespaces, it seems my custom namespace is not linked to my localized resource file.
I've been searching for hours to find a solution for a C++ CLR/CLI project which is pretty different comparing with C# projects which apparently comes with Build Action and Custom Tool Namespace all these options we don't have in a CLR/CLI project, it's really important, especially if we have changed Namespaces so we gotta use Resource Logical Name instead. Here's my answer how to solve Namespace issues, this also works for localized resource files linked to satellite dlls.
After your localized satellite dll is generated, include that in your project as Compiled Managed Resource you can set that by opening its file property and setting the Item Type. In projects such as C# you won't find that but something similar like "Embedded Resource". Anyways this is intended to C++ CLR/CLI projects only. If you have changed namespaces, don't forget to set Resource Logical Name of the respective resource file.
Next step is to do some code in order to embed that dll into our exe application, here's a good one for that:
Since C++ CLR/CLI doesn't support lambda expressions we have to do this way:
private: System::Reflection::Assembly^ currentDomainAssemblyResolve(System::Object^ sender, System::ResolveEventArgs^ args) {
System::Reflection::AssemblyName^ assemblyName = gcnew System::Reflection::AssemblyName(args->Name);
System::String^ resourceName = assemblyName->Name + ".dll";
System::IO::Stream^ stream = System::Reflection::Assembly::GetExecutingAssembly()->GetManifestResourceStream(resourceName);
array<Byte>^ assemblyData = gcnew array<Byte>((unsigned long) stream->Length);
try {
stream->Read(assemblyData, 0, assemblyData->Length);
} finally {
if (stream != nullptr) delete stream;
}
return System::Reflection::Assembly::Load(assemblyData);
}
Usage:
//Put it in your constructor before InitializeComponent()
MyClass(void) {
AppDomain::CurrentDomain->AssemblyResolve += gcnew System::ResolveEventHandler(this, &MyNameSpace::MyClass::currentDomainAssemblyResolve);
InitializeComponent();
}
So now it's no longer necessary satellite dlls to load your localized resources.
Use a free application packer to bundle files into a single exe.
https://enigmaprotector.com/en/aboutvb.html
This one is free, I use it and it works very well for me.

Qt #define "signals" clashes with GStreamer (gst)

Qt, which seems to name everything else with an initial Q, does this: #define signals signals in qobjectdefs.h.
However, GStream, not naturally, does not imagine signals to be a reserved word and does this
struct _GDBusInterfaceInfo
{
/*< public >*/
volatile gint ref_count;
gchar *name;
GDBusMethodInfo **methods;
GDBusSignalInfo **signals; <==================
GDBusPropertyInfo **properties;
GDBusAnnotationInfo **annotations;
};
in gdbusintrospection.h.
Am I just to assume that Qt and GStreamer don't play well together., or is there a way around this?
Note: Qt can be persuaded to #define signals signals if I don't #define Q_MOC_RUN. But that leads to problems with classes which are using
class
{
public:
// stuff
signals:
// stuff
private:
// stuff
};
As you might have guessed by now, I am trying to take over code from someone who is not around to support it and Google is not my friend:-(
[Update] Thanks, #IpApp fro the tip (which is not working, alas).
I have been given someone else's code. Apparently it build for target, but has never been built for unit test and I have to do that (why he mix & matched, I do not know).
When I use QT_NO_KEYWORDS in Eclipse CDT, I get errors because the class definition code does not use Q_SINGAL(S) - it uses the signals macro (which is now defined as signals) to define certain public members.
I am not allowed to alter the subsytsem code, just to mock its interfaces, but I am loathe to mock all of Qt & Glib, because of the effort.
Perhaps there is a way to use libraries for one or the other, rather than including their directories into the source path?
Just follow this documentation in your qmake project file:
CONFIG += no_keywords
If you are using something else than qmake, make sure that you define the following in your buildsystem:
QT_NO_KEYWORDS
Then, you need to make sure that you use Q_SIGNALS or Q_SIGNAL all over the place in your headers so that moc (meta object compiler) is still notified that it is a signal.
I have found another solution which as for me is more convenient and simple - you should include glib headers before Qt headers, and thats all. As glib code goes before, it is unaffected by Qt define statements.

Problems interfacing SWI-Prolog to C++

i am at wit's end trying to make SWI-Prolog play nice with C++. Now, before i start explaining exactly what my problem is, i want to first state what my project is about and what tools i chose in order to develop a solution.
My professor assigned to me the task of developing a GUI program that serves as a frontend to SWI-prolog, and this frontend is to be developed in C++. I chose to use Qt to design the GUI and use C++ as a backend to bridge SWI-Prolog to the application. The user of this application should be able to input some lists and then choose operations to be applied to them through prolog, like if, for example, I input a list of numbers, then by click of a button the user gets another list of all the numbers that are pairs in this list (if there are any). I am developing on a unix OS, more specifically, netrunner rolling release, based on archlinux and manjaro.
I did some research, and it seemed that the best course of action in order to interface SWI-Prolog (may i also mention that my professor also recommended this), is to use the header and source file developed by Volker Wysk; for reference, here is the link to the compressed file that contains these files http://www.volker-wysk.de/swiprolog-c++/index.html
Now here is my problem: if you visited the page i just gave you you will see that this C++ implementation of the SWI-Prolog interface is quite old: last time it was worked on was in the year 2002. I had to modify the header file so that i could get rid of some of the errors, like putting using namespace std or changing #include ostream.h to #include ostream, and so i managed to get the error count to only two which i can't manage to fix and which i think i won't be able to because there are two functions whose implementation i can't find anywhere: the function is declared but the code that it is supposed to run when they are called can't be found.
I will now list the contents of the files i consider to be most relevant. I have the latest version of SWI-Prolog installed, and so the SWI-Prolog.h header is the latest one that comes with the installation of the newest prolog (version 6.6.5).
#-------------------------------------------------
#
# Project created by QtCreator 2014-07-05T12:38:45
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = prologFrontend
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp \
../../../../../../../../usr/local/share/swiprolog-c++/prolog.cpp
LIBS += -L/usr/lib/swipl-6.6.5/lib/x86_64-linux -lswipl
HEADERS += mainwindow.h
FORMS += mainwindow.ui
contents of the prologFrontend.pro file (Qt creator project file)
#include "mainwindow.h"
#include <QApplication>
#include <prolog.hpp>
int main(int argc, char *argv[])
{
try {
Prolog_impl::prolog_init(argc, argv);
} catch(Prolog_impl::PlError &error) {
}
QApplication prog(argc, argv);
MainWindow w;
w.show();
return prog.exec();
}
contents of the main.cpp file
I would copy the whole contents of the header and source files made by Volker Wysk, but it's too long to fit in here. You can take a look at them if you download it from the link to his site i already posted. Next are the errors i am getting and the two corresponding code snippets where they happen in the .cpp file that he made:
// part of SWI-Prolog, but not exportet by header file
// /usr/local/src/swiprolog-4.0.9/src/pl-funcs.h
//NOTE: this function is declared here but it's even not to be found in the header file
//prolog.hpp. Its implementation can't be found anywhere using the function definition
//navigation capability of Qt so, basically, its a function that does nothing.
extern "C"{
unsigned long pl_atom_to_term(term_t in_atom,
term_t out_term,
term_t out_bindings);
}
bool Prolog_impl::atom_to_term(const char* text, Term* t, list<Term::Binding>* b)
{
Term in_atom = Atom(text);
Term out_term;
Term out_bindings;
if (!pl_atom_to_term(in_atom.lsi, out_term.lsi, out_bindings.lsi))
return false;
if (t) *t = out_term;
if (b) *b = out_bindings;
return true;
}
And the error that this code throws: /usr/local/share/swiprolog-c++/prolog.cpp:45: error: undefined reference to `pl_atom_to_term'.
//Note that this code has the same issues as the one above: no implementation to be found
extern "C"{
unsigned long pl_copy_term(term_t in, term_t out);
}
Term Prolog_impl::copy_term(Term t)
{
term_t t2 = PL_new_term_ref();
if (!pl_copy_term(t.lsi, t2))
throw LogicError("copy_term(Term)", "failure calling pl_copy_term()");
return Term(t2);
}
and the error that this code throws: /usr/local/share/swiprolog-c++/prolog.cpp:60: error: undefined reference to `pl_copy_term'.
Aside from the changes I had to make to the header file I already mentioned, I had to fix this line of code in the header file:
#include <SWI-Prolog.h>
to this:
#include "/usr/lib/swipl-6.6.5/include/SWI-Prolog.h"
This is because, otherwise, the compiler complains that it can't find that header file.
My guess is that these functions used to exist in an older SWI-Prolog version. I have no real clue about what to do with this task, i tried reading up on other alternatives to using volker's implementation but it's like there is close to none good information on the net about how to interface Prolog with C++.
Thank you so very much for taking your time to read my question. If you have a solution that works, please let me know. It doesn't have to be SWI-Prolog, it could be any other Prolog environment that interfaces nicely with C++ and that uses more or less about the same syntax that SWI-Prolog uses, though i think that the syntax is already standard for all environments.
Package swipl-win is a working SWI-Prolog / Qt interface, portable on Linux,MacOS,Windows. I have many others here, but these are restricted to running on Linux by now...
I wonder why, apart Qt specific problems, have you chosen an old, unmaintained C++ interface, when there is an 'official' one here. This interface is working pretty well, giving parameter validation based on exception handling and automatic type conversion. Then it's easy to add to the interface - for instance, from PREDICATE.h
typedef PlTerm T;
#define LOOP__ { } operator bool() { return next_solution(); }
#define query0(P) struct P : PlQuery { P() : PlQuery(#P, V()) LOOP__ };
#define query1(P) struct P : PlQuery { P(T A) : PlQuery(#P, V(A)) LOOP__ };
...
allows
query1(current_predicate)
void Completion::initialize(QSet<QString> &strings, bool reload) {
Q_UNUSED(reload)
T PRED;
for (current_predicate cp(PRED); cp; ) {
QString p = t2w(PRED);
if (p[0].isLetter())
strings.insert(p);
}
qDebug() << "Completion::initialize loaded" << strings.count();
}
About your specific problems, probably those functions are obsolete, you should stick to C Api (also know as foreign language interface) documented here.
Looking into the Makefile for swiprolog-c++-0.1.0, it looks like a special linker needs to be used, called plld. So you need to use your usual compiler to generate only the object files, then use that linker to create the executable.
The plld line in the makefile looks like this:
main : main.o prolog.o test.pl
plld -o $# -ld $(CC) $^ -lstdc++
The "recipe" line expands to this:
plld -o main -ld gcc main.o prolog.o test.pl -lstdc++

Not sure how to use QtTest

I want to do unit testing for some simple exercises i have done in c++ using Qt. i figured using QtTest seemed like a reasonable place to start.
i have a class that returns an integer and i want to test that the expected result is the same as the actual.
am i right in thinking i make a new c++ source file in the project to use as the QtTest
heres what i have but from reading the Qt documentation i cant work out what i have to do?
#include "Conversion.h"
#include <QtTest/QtTest>
class ConversionTest : public QObject
{
private slots:
void testConvert();
};
void ConversionTest::testConvert()
{
int unit1 = 1, unit2 = 10;
std::string sUnit1 = "stone", sUnit2 = "pound";
double expected = 10.8862;
double actual;
Conversion c;
actual = c.convert(unit1, unit2, sUnit1, sUnit2);
QCOMPARE(expected, actual);
}
QTEST_MAIN (ConversionTest)
#include "conversiontest.moc"
this is what i produced after reading the documentation but now what how do i run it and get the (what i think is) console output that says pass/fail?
any help would be great thanks
You need to create an app with it (QTEST_MAIN(..) builds the main function for you), and specify CONFIG += qtestlib in the .pro file.
When you run it, a console opens that prints out the test results.
I solved this myself the problem was just Qt errors no problem with the code at all, for some reason it didnt like that my project files were in a folder structure of more than one folder before my project files, used the exact same code in a new dir and it worked?? :S