Can Qt Remote Objects be used to share an entire mainwindow UI? - c++

I'm currently looking into Qt RO as a possible solution for my current need to remotely access a UI without using Qt WebGL. I am having trouble finding any good example uses of Qt RO outside of the starter ones in the qt docs.
Will Qt RO fit my needs and does anyone know of a good example?

Custom types work just fine with Qt Remote Objects. Just like with any other meta object compiler issue in Nuke, you just need to make sure that the type is known to the meta object compiler.
So, for example, you will need to register it.
PROP(SomeOtherType myCustomType) // Custom types work. Needs
#include for the
// appropriate header for your type, make
// sure your type is known to the metabject
// system, and make sure it supports Queued
// Connections (see Q_DECLARE_METATYPE and
// qRegisterMetaType)
https://doc.qt.io/qt-6/qtremoteobjects-repc.html#prop
You can also find more information about how to handle custom types in Qt in general here. You would register your type like this:
Q_DECLARE_METATYPE(Message);
https://doc.qt.io/qt-6/custom-types.html

Related

Qt5: Call main-application functions from within a plugin

I am currently messing around with plugins in Qt5 (QPlugin). More specifically I have been looking into this example:
https://doc.qt.io/qt-5/qtwidgets-tools-echoplugin-example.html
There they create an abstract interface class to access functions in the plugin. Now here comes the question: Does this work the other way around?
Say I do stuff in my plugin and want to print some results to a GUI which lives in the main application. Can I call GUI functions from within the plugin? Or is there another way to achieve this kind of communication from plugin to application?
Messed a bit around and...
Answer was, to simply send the Main GUI's pointer as parameter of one of the interface functions and storing that pointer in the plugin class. That way, you can access the GUI (and other classes in the main application) from within the plugin.

program NSTouchBar with c++

The problem
I would like to use c++ to create an application that uses the new macbook pro touch bar. However I am not able to find any really good resources. And apple does not have any docs on using c++ to program the touch bar.
What I have done
I found this article on c++ and the touch bar, However I cannot find either of the header files for the script GLFW/glfw3.h and GLFW/glfw3native.h. These both seem critical to the script working.
More on the issue
Even if the above article's script works, there are no official docs for programing the touch bar with c++ (That I know of). I think that this is an important thing to have given the fact that many, if not most applications are written in c/c++.
Thank you in advance for the help!
So the article that you link to basically does not need the GLFW/glfw3.h and GLFW/glfw3native.h files if you are not using GLFW.
What UI framework are you using for your C++ app?
Unless it is still using Carbon, at the lowest level, the framework will be creating NSWindows to actually have windows in the UI. You need to get access to the NSWindow that your framework is using to host it the UI. If it is still using Carbon, I think you are probably not going to be able to accomplish this.
If the framework provides some mechanism to get the native platform window (which will be an NSWindow), you would replace the author's call to glfwGetCocoaWindow(window); with the correct call from your framework.
If the framework does not provide access to the NSWindow, then you will need to use the code that is commented out at the bottom of the article to attach your touchbar to the windows in your app.
Please note that all that code is Obj-C code; you'll need to have at least one .m or .mm file in your project to provide that Obj-C glue code to get access to the touchbar. Basically that code is a C-calleable wrapper around the Cocoa API.
Also note that you'll need to expand the list of buttons and actions for all the different things you want to put in the touchbar. You could add your own wrapping API so that the construction of the toolbar is done from C++ and registers actions that call-back into your C++ app to handle the events.
Fundamentally though, the touchbar is not available on any other platform, so there is no great benefit to trying to avoid writing Obj-C to implement your touchbar as that code will only run on macOS anyway. If you use .mm files to implement Obj-C++ for this code, you can still call into your C++ objects from your touchbar code.

Protecting QML source code from plagiarism

The goal is to come up with a way to protect your QML code from plagiarism. It is a problem, since the way QML was designed and implemented seems to be inexplicably unprotected in this regard. The only QML types which are somewhat protected are those implemented entirely in C++.
Qt resource files don't support any degree of protection
even if you compress the resource file, extracting data from it is still fairly trivial to anyone with moderate experience
QML files stored on the file system are practically there for the taking
the same applies to any remote QML files, aside from adding dependency on internet connection, it is easy to sniff on the network access and get the QML files through their urls
QML doesn't provide seem to provide any public API to allow users enough control over QML type resolution to protect their code
All in all, it almost looks like Qt deliberately skimps on QML code protection, one obvious candidate reason would be to force people into buying the insanely expressive commercial license, which features the QML compiler.
So absent any stock method of protecting QML sources, the only solution that currently comes to my mind is control over how QML types are resolved. There are several ways of registering types to QML:
register in the application executable
register in a plugin
register via a QML module
However, what I need is to manually resolve QML types, much like you can create a custom QQuickImageProvider which inputs a URL string and outputs an image, I need the QML engine to request a string with the type to my custom component provider which outputs a ready for object instantiation component.
This would be easy if any custom instantiation mechanism is used, but I need those types to be usable in regular QML sources. Ideally this should be the first mechanism used to resolve the type, before looking in the available import paths or even internally registered types.
Alternatively, it would be just as useful if there is a way to define a QML module entirely in C++, without any external QML files, without a qmldir file and so on.
As a last resort, and falling short from ideally, I would also settle for registering QML (not C++) types to the runtime, this could also be useful, but I'd prefer to have full control over the resolving process.
A QML plugin does not do the trick, as it registers C++ types, and I want to register QML types, that is, QQmlComponents created from string sources and referencing each other.
The (ideal) Solution: Precompile it
The Qt Quick Compiler is a development add-on for Qt Quick applications which allows you to compile QML source code into the final binary. As it's description says, it will help on preventing plagiarism and it will also enhance your application launch times and provide other benefits.
This is as close as you can get to protecting your QML source code, even when it's not yet fully optimized
Update
As of Qt 5.11 the solution is in place and getting better fast.
Update (2)
Seems the QML compiler is already opensource from 5.11 I can't tell about tooling but Lars Knoll explains it on the blog post.
Option A) use qtquick compiler
Option B) use encrypted resources:
compile resources into separated file:
rcc -binary your_resource.qrc -o extresources.rcc
encrypt extresources.rcc to extresources.rcc.cr (for example with gnupg)
create a new resource file APP.rcc, only with extresources.rcc.cr file
on startup, load ":/extresources.rcc.cr" and decrypt them into buffer (you need a cryptographic library like Libgcrypt ...hide private key for decompilers and debuggers etc)
Q_CLEANUP_RESOURCE(APP); (optional, clear APP.rcc for saving memory)
Resource::registerResource((unsigned char *) myBuffer.constData()))
//now, you have available decrypted resources...for example
engine.load(QUrl("qrc:/main.qml"))
Real implementation is not trivial, but works very good...
Actually, you can register QML types in C++. The function qmlRegisterType has an overlapped form which accepts a QUrl denoting to a qml file in qrc:
qmlRegisterType(QUrl("qrc:/YourQMLModule.qml"), "YourModule", 1, 0, "YourQMLModule");
It just looks like you register a normal C++ class. It is commonly used in Qt's official sources, though be missing on the documentation.
After some digging around I found two directions that might be worth pursuing:
using a custom QQmlAbstractUrlInterceptor for the QML engine, that resolves QML types and returs a QUrl, in the case of "protected" types, the interceptor can prepend a custom scheme. The using a custom QNetworkAccessManager to intercept that url, calls the default implementation for unprotected types and for protected types decrypts the data and returns it in a QNetworkReply.
another, simpler but less flexible solution involves only the second part of the previous solution, and the qmlRegisterType(const QUrl &url, ...) function to expose as QML types, avoiding the usage of the interceptor.
I will post updates as I investigate those two. Note that this is not 100% secure either, as the network reply with the decrypted code itself will at least temporarily stay in RAM, so given enough competence it would still be possible to get to the code, however it is not as trivial as taking it directly from the application binary. A possible direction to go even further would be to resort to a custom QNetworkReply which doesn't contain the decrypted data, but overloads the QIODevice part to act as an accessor to the encrypted data that decrypts it along the way while reading it.

Isavailable is not a member of QSound

I want to compile some old QT project with QT 5.2.1 and have many trouble, one of which is QSound problem:
if(!QSound::isAvailable()) {
ui.grpSounds->setEnabled(false);
ui.grpSounds->setTitle(tr("Sounds (Not Available)"));
}
error:
'isAvailable' is not a member of 'QSound'
will anyone help me? I am completely newbie with Qt.
Thank you.
If you want to notify the user whether or not sounds can be played then your best bet is QAudioDeviceInfo. You can query for available input or output devices using the static method
QList<QAudioDeviceInfo> QAudioDeviceInfo::availableDevices(QAudio::Mode mode)
For instance you can replace QSound::isAvailable() by
!QAudioDeviceInfo::availableDevices(QAudio::AudioOutput).isEmpty()
Edit:
QSound was part of the gui module, but now is part of the multimedia module (which make more sense). You need take a look at the changes in multimedia modules from Qt4 to Qt5 for more info. You may also want to look at QSoundEffect, which seems to have a richer API
According to class reference, Qt 5.2 don't have Sound::isAvailable() static method http://qt-project.org/doc/qt-5/qsound.html
It was in Qt4.8

OS X from Carbon to Cocoa window creation?

Edit: This question has been answered indirectly in the comments (using GLUT to avoid the need for either) but because its not posted as an answer, I cannot "accept" it although my issue is solved.
I have a cross platform OpenGL application, written in C++, that (on Mac OS X) uses Carbon for the window creation and message pump (Think...NeHe Lesson 1). Recent changes to my code utilizing C++11 features has made it incompatible with the GCC that comes bundled with XCode.
All of my attempts to use systems like MacPorts, HomeBrew, etc... have failed for different reasons (Mostly due to my need to compile 32bit for Carbon support). I was originally going to ask if anyone had a better solution for installing an updated G++ in Mac OS X 10.8.
That seems like a short sighted solution (at some point, I will need to upgrade to Cocoa and 64bit) so my question has evolved to asking what would be the most simple way to have my existing (very large) application utilize Cocoa for this task rather than Carbon?
I have all of the "Carbon Code" in its own separate .cpp/.h file, which has only two functions, one to create an OpenGL window, and one that is a message pump that uses ReceiveNextEvent.
Edit:
To be clearer, I am looking for the best way to design (more or less) a drop in replacement for my existing Carbon window creation, and message pump functions, but in Cocoa. I understand that being a different API, using different language concepts, that a simple one to one command replacement will not suffice. My existing code has a source code file for Mac that has two functions which perform core tasks (with Carbon) that I call, InitWindow, and DoEvents. These create the window, and cycle through the pending events respectively. It is my goal to replace this source code file with one that uses Cocoa, exposing the same functions so there is little to no modification of my core code.
What would be the best way to achieve my goal? I am not familiar with Cocoa and Obj-C is alien to me.
Going to Cocoa 64-bit definitely sounds like a great idea. And I recommend using some of the native UI if you want to make your users happy, too.
The easiest thing to do would be to create an NSWindow with an NSOpenGLView in it. You can either do that in Interface Builder, or in code. It's probably best to do it by creating a new Cocoa app using Xcode's template (File > New Project > Cocoa App). That will give you a window by default. You can open it in Interface Builder and add an NSOpenGLView to it. You can make the view a custom subclass of NSOpenGLView, and add your event handling to it. See the docs for NSResponder for more information on how Cocoa dispatches events.