Qt, Signals without naming? - c++

Is there any way to use the signals without MOC and without the connecting via names? My one problem with Qt is that you have something like
this->connect(this->SaveBtn, SIGNAL(click()), SLOT(SaveClicked()));
And there is no error detection to tell that is wrong other then finding out the button doesn't work or searching through their documentation to find out the signal doesn't exist. Also it seems pointless and a waste of cycles to connect via names instead of classes.

There is error detection, the connect function returns false when it fails to connect, and a warning is output on standard error (or, on Windows, to the weird place which DebugView reads from). Also you can make these warnings into fatal errors by setting QT_FATAL_WARNINGS=1 in your environment.
It's not pointless to connect by name. For example, it means that connections can be established where the signal/slot names are generated at runtime.

Other than the fact that signals are just methods, no I don't think you can use them like they are intended without the intermediate MOC step. It is a pain when you mess up the connection and there is no flag raised. What does your last sentence mean? Can you elaborate what your problem is? Signals/Slots is not a perfect system, I don't think a perfect system exits, but it is pretty intuitive and has worked well for me.

No, there is no real way around that.
You'll have to use MOC and connect via names. But with time you'll find out that it "grows on you" and won't really bother you. Train yourself to add code in small snippets each time, testing that what you added works, and you'll have no trouble with this.

I normally Practice following style of coding,
m_pCancelPushButton = new QPushButton(tr("Cancel"));
m_pCancelPushButton->setObjectName("CancelButton");
//MetaObject Connections
QMetaObject::connectSlotsByName (this);
This enable me to write code
void Class_name::on_CancelButton_clicked()
{
//Do your job here.
reject();
}
I hope it will help you.
Thanks,
Rahul

Related

Synchronous single file download - is it the right approach in a GUI Qt application?

I'm developing an updater for my application in Qt, primarily to get to know the framework (I realize there are multiple ready-made solutions available, that's not relevant here). It is a basic GUI application using a QMainWindow subclass for its main window and an MyAppUpdater class to perform the actual program logic.
The update information (version, changelog, files to be downloaded) is stored on my server as an XML file. The first thing the updater should do after it sets up the UI is query that server, get the XML file, parse it and display info to the user. Here's where I have a problem though; coming from a procedural/C background, I'd initiate a synchronous download, set a timeout of maybe 3 seconds, then see what happens - if I manage to download the file correctly, I'll parse it and carry on, otherwise display an error.
However, seeing how inconvenient something like that is to implement in Qt, I've come to believe that its network classes are designed in a different way, with a different approach in mind.
I was thinking about initiating an asynchronous download in, say, InitVersionInfoDownload, and then connecting QNetworkReply's finished signal to a slot called VersionInfoDownloadComplete, or something along these lines. I'd also need a timer somewhere to implement timeout checks - if the slot is not invoked after say 3 seconds, the update should be aborted. However, this approach seems overly complicated and in general inadequate to the situation; I cannot proceed without retrieving this file from the server, or indeed do anything while waiting for it to be downloaded, so an asynchronous approach seems inappropriate in general.
Am I mistaken about that, or is there a better way?
TL;DR: It's the wrong approach in any GUI application.
how inconvenient something like that is to implement in Qt
It's not meant to be convenient, since whenever I see a shipping product that behaves that way, I have an urge to have a stern talk with the developers. Blocking the GUI is a usability nightmare. You never want to code that way.
coming from a procedural/C background, I'd initiate a synchronous download, set a timeout of maybe 3 seconds, then see what happens
If you write any sort of machine or interface control code in C, you probably don't want it to be synchronous either. You'd set up a state machine and process everything asynchronously. When coding embedded C applications, state machines make hard things downright trivial. There are several solutions out there, QP/C would be a first class example.
was thinking about initiating an asynchronous download in, say, InitVersionInfoDownload, and then connecting QNetworkReply's finished signal to a slot called VersionInfoDownloadComplete, or something along these lines. I'd also need a timer somewhere to implement timeout checks - if the slot is not invoked after say 3 seconds, the update should be aborted. However, this approach seems overly complicated
It is trivial. You can't discuss such things without showing your code: perhaps you've implemented it in some horribly verbose manner. When done correctly, it's supposed to look lean and sweet. For some inspiration, see this answer.
I cannot proceed without retrieving this file from the server, or indeed do anything while waiting for it to be downloaded
That's patently false. Your user might wish to cancel the update and exit your application, or resize its window, or minimize/maximize it, or check the existing version, or the OS might require a window repaint, or ...
Remember: Your user and the environment are in control. An application unresponsive by design is not only horrible user experience, but also makes your code harder to comprehend and test. Pseudo-synchronous spaghetti gets out of hand real quick. With async design, it's trivial to use signal spy or other products to introspect what the application is doing, where it's stuck, etc.

How to detect when ssh connection (over a QProcess) has finished?

I am running an ssh tunnel from an application using a QProcess:
QProcess* process = new QProcess();
process->start("ssh", QStringList()<<"-L"<<"27017:localhost:27017"<<"example.com");
So far it works great, the only problem being that there is no way for me to see when the port has actually been created.
When I run the command on a shell, it takes about 10 seconds to connect to the remote host after which the forwarded port is ready for usage. How do I detect it from my application?
EDIT:
As suggested by vahancho, I used the fact that post-connection there is some output on the terminal that can be used to detect that the connection has succeeded. However, there is a line which is run instantly after launch Pseudo-terminal will not be allocated because stdin is not a terminal, which probably would give a false alarm. The correct output is available in the second signal, emitted a bit later (which is a true indicator of the port having being opened). To get rid of the first message, I am now running ssh using ssh -t -t to force an stdin allocation.
So, the only question left is, can anyone help me without any concerns in this approach?
So, the only question left is, can anyone help me without any concerns in this approach?
This is not a stable and robust solution, unfortunately. It is similarly a broken concept to handling git outputs rather than using an actual library. The main problem is that these softwares do not have any guarantee for output compatibility, rightfully.
Just imagine that what happens if they have an unclear text, a typo, et all, unnoticed. They inherently need to fix the output respectively, and all the applications relying on the output would abruptly break.
This is also the reason behind working on dedicated libraries giving access to the functionality for reuse rather than working with the user facing output directly. In case of git, this means the libgit2 library, for instance.
Qt does not have an ssh mechanism in place by default like you can have such libraries in python, e.g. paramiko.
I would suggest to establish a way in your code by using libssh or libssh2 as you also noted yourself in the comment. I can understand the inconvenience that is not a truly Qt'ish way as of now, but at this point Qt cannot provide anything more robust without third-party.
That being said, it would be nice to see a similar add-on library in the Qt Project for the future, but this may not be happen any soon. If you write your software with proper design in mind, you will be able to switch to such a library withour major issues once someone stands up to maintain such an additional library to Qt or elsewhere.
I had the same problem, but in my case ssh do not output anything - so I couldn't just wait for output. I'm also using ssh to setupt tunnel, so I used QTcpSocket:
program = "ssh";
arguments << m_host << "-N" << "-L" << QString("3306:%1:3306").arg(m_host);
connect(tunnelProcess, &QProcess::started, this, &Database::waitForTunnel);
tunnelProcess->start(program, arguments);
waitForTunnel() slot:
QTcpSocket sock;
sock.connectToHost("127.0.0.1", 3306);
if(sock.waitForConnected(100000))
{
sock.disconnectFromHost();
openDatabaseConnection();
}
else
qDebug() << "timeout";
I hope this will help future people finding this question ;)

How do I get a `callFrameID` to pass to `Debugger.evaluateOnCallFrame`?

WebKit's Remote Debugging Protocol went 1.0 recently and I've been playing around with it a little, mostly out of curiosity and interest. I've thrown together a very basic recreation of Chrome's developer tools console as a replacement front-end, but I'm a little confused as to how I can execute code in a specific frame/window like Chrome's Dev Tools allow you to.
At the moment, I'm using the Runtime.evaluate method to execute my console input. This seems inadequate because of the aforementioned problem and it doesn't provide the command line API. I've discovered the Debugger.evaluateOnCallFrame method, which requires a callFrameID parameter. The only problem is, it doesn't seem possible to remotely acquire a list of callFrame objects to pass to this method.
I have a feeling I'm completely missing something here. Does anyone know the solution?
Have a look at the Debugger.paused event, which will give you an array of current call frames.

c++ winsock code does not work in its original solution/project in visual studio 2010

I am not 100% sure if I shall become insane...
As mentioned in many many other posts, I am writing this Connection class which stats up winsock, creates some sockets, binds them and let´s you send and receive some data...
I made this within my Server-project...
But , everytime i wanted to test the connection part of the server (most of the other parts are already working fine) it always goes on strike O_o... ALWAYS!!!...
What I tried to fix it:
1. rewrite the send & recv parts
2. rewrite the whole class multiple times without copying anything from the existing stuff before...
3. Write a special test client...
4. Write a whole new simple send/recv-udp-server programm to test, wether it may be based on some ports, that are blocked or something like that...
Still does not work...
Well... so a few minutes i came up with the idea, that I could try to copy the code into a new project and try it then (I don´t know what made try this - the frustration?.
But wooaaaaaah... IT WORKS:...
Now my Question to anyone familiar with Visual Studio...:
Why the HELL doesn´t it work in the original soultion/project, but In a totally new solution/project...???????
This drives me crazy, because I have to copy/rewrite everything into a new solution and reorganize this shit-.-....
All that I can say is to check all properties of old project which does not work against new project working...
It should be something different since you said that you did not modify the source code.
Occasionally the IDE will get confused and fail to correctly determine what needs to be recompiled. When strange stuff happens try "Rebuild Solution", or better yet, exit from the IDE and then rebuild.
Ok... I am not sure, why this problem appeared...
But the solution was to create a new solution and insert the "old" files...
finally it works :)...
I hope it wasn´t the windows firewall, but I did check this...

IThumbnailProvider and IInitializeWithItem

I am trying to develop an IThumbnailProvider for use in Windows 7. Since this particular thumbnail would also be dependant on some other files in the same directory, I need to use something other than IInitializeWithStream to a path to work with, this being IInitializeWithItem. (Alternatively, I could use IInitializeWithFile, but that is even more frowned upon apparently.)
No matter what I do, I cannot get it to work. I have Microsoft's FileTypeVerifier.exe tool which gives the green light on using IInitializeWithItem, but when explorer calls it, it only seems to try IInitializeWithStream, ever. (This was tested by temporarily implementing said interface, and Beep()ing away in its Initialize()) Did I forget to configure something?
In short: how do I get this to work?
Okay, I finally found out what is the matter. To quote the Building Thumbnail Providers link on the MSDN website:
There are cases where initialization with streams is not possible. In scenarios where your thumbnail provider does not implement IInitializeWithStream, it must opt out of running in the isolated process where the system indexer places it by default when there is a change to the stream. To opt out of the process isolation feature, set the following registry value.
HKEY_CLASSES_ROOT
CLSID
{66742402-F9B9-11D1-A202-0000F81FEDEE}
DisableProcessIsolation = 1
I knew I was running out of process since I read elsewhere that thumbnailproviders ALWAYS ran out of process. But since that particular snippet is on almost -all- shell extension handlers, I interpreted it to be a overly happy copy-paste job, since it was -required- to run in-process the way I understood it.
And I was wrong. I hope this will help someone else in the near future. :)