PDA

View Full Version : How to use separate threads for pushbuttons in QT (like SwingWorker in Java)



artt
13th December 2015, 18:01
I need to realize several buttons (as well as Qlabels, QtextEdit) in QWidget.
But I need to do it non-lockable, so if it is executinh a long time, it should be not hanging.
In java it works very fine with SwingWorker class, but not with Runnable.
So I need to know what analog I need to use in Qt.
Here is excerpts from java code. As it is very compact so I need to follow it in Qt but with local
classes:


class Writefile extends SwingWorker {//Declaration of custom thread class
public Object doInBackground() {
XMLCreator.stax();//class and method that realize XML writing to file.
return null;
}

writetofile.addActionListener(new ActionListener() { //adding listener to button
public void actionPerformed(ActionEvent e) {
//XMLCreator.stax();
Writefile process = new Writefile(); //initizalization of swingworjer class
process.execute(); //starting separate task in separate thread
}
});
So how should I use
Qtobject::connect(writebutton,SIGNAL(clicked()), this, SLOT(Filewalker::writetofile())); //The last is the slot declared in Filewalker class header

d_stranz
13th December 2015, 18:31
All QWidget instances must be created and run in the main GUI thread.

What you might be able to do is to send a signal to a different thread upon a push-button click. That is, the pushbutton click is handled in a slot in the main thread, but it sends a signal to a non-GUI handler slot in a different thread.

Google for Wysota's excellent article on "Keeping the GUI responsive".

artt
13th December 2015, 18:52
There is an part about workerthread: Qthread. So I do understand that I need to extend the Qthread, put the
Filewalker::writetofile() in run() method then just initialize Qthread2 in Qwidget in such way as
Qthread2 writes; And then put it in connect method in slot like SLOT(writes.exec()).


Qtobject::connect(writebutton,SIGNAL(clicked()), this, SLOT(Filewalker::writetofile()));
Qtobject::connect(writebutton,SIGNAL(clicked()), &writes, SLOT(writes.exec());

If so should I use "this" in the connect 3-rd argument, or put the instance of Qthread2?
//Despite in QAssistant the start() is prevalent, as I see, to exec().
//There is also the question about how and where (in what file) to declare and initialize several Qthreads?
In Java - I do it in Jframe file, could I do it in Qwidget file?

anda_skoa
13th December 2015, 22:29
Despite in QAssistant the start() is prevalent, as I see, to exec().

QThread::start() starts the thread, i.e. requests a thread from the operating system and lets it execute run().

QThread::exec() can be called from within run() to start the thread's event loop. The default implementation of QThread::run() basically does just that.



If so should I use "this" in the connect 3-rd argument, or put the instance of Qthread2?

The third argument of connect() is the receiver object, so it depends which object you want to execute the slot on.

The equivalent to your Java code would be to connect to "this" and in that slot create the worker thread and start it.

Cheers,
_

artt
13th December 2015, 23:14
I though that I should do in such way(I didnot explored Qthread enough yet):


class Writefile: public QThread {
public void run() {
Filewalker::writetoXML();
}
}

here is question is it enough just put Filewalker.h (just with Filewalker::writetoXML() declaration, but definition in main.cpp --really seems improbable, so I think I need to create header for writetoXML() --writetoXML.h ) in aforementioned file with Writefile
then, to initialize Qthread in QWidget:


Writefile wr; //(or Writefile* wr=new WriteFile();)
Qtobject::connect(writebutton,SIGNAL(clicked()), this (//or &wr), SLOT(wr.exec() //or wr.start);

What is incorrect, it is my blueprint...

So should I Extend MyWidget the Qobject or can I realize just with main(widget).cpp --that is--should I declare the slots in final Widget file or in initial file such as FileWalker.h
or methodheader - writetoXML.h?

So maybe I should abstain of this console file from here http://www.qtcentre.org/threads/64555-Why-my-walker-application-hangs-due-to-fubction-recursion?p=285197#post285197 and put all definition of
slots (that are functions from Filewalker) in one big Widget File that defines such functions as (indexate files, writetoxml, renderxml, searchbyname) with QButtons, Qlabels, and connect statements.
The question is appered in such case -- where to define Qthread class for every button (in header?), and then initialize it in Widget file???

anda_skoa
14th December 2015, 07:15
here is question is it enough just put Filewalker.h (just with Filewalker::writetoXML() declaration, but definition in main.cpp

Yes



What is incorrect, it is my blueprint...

The SLOT macro needs a slot signature. That is the slot's name and, if applicable, all argument types.



should I declare the slots in final Widget file

Well, that is a non-question, the slot needs to be a member of the receiver class, which is already declared somewhere.
So if "this" is your receiver object, then the slot will be part of the declaration of that class.



where to define Qthread class for every button (in header?), and then initialize it in Widget file???

If you want to keep references to the thread(s) then yes, as a member of the class that starts them would be a good choice.

Cheers,
_

yeye_olive
14th December 2015, 09:49
Why bother with QThreads? Just use QtConcurrent::run(). Here:

...
connect(myButton, SIGNAL(clicked()), SLOT(runMyFunctionInAnotherThread()));
...
void myFunction() {
// This function is not meant to be run in the GUI thread
}
...
void MyClass::runMyFunctionInAnotherThread() {
QtConcurrent::run(myFunction);
}

anda_skoa
14th December 2015, 12:35
QtConcurrent::run() might be a bit weird to use when the function generates a result (usage of the QFuture API).

One also needs to be aware that the number of threads is limited, especially when using the overload that does not take a thread pool but uses the global instance.

And at least in one occasion I had a task not run in a separate thread. Not sure if that was a bug or something like work-stealing in case of an overloaded thread pool, I don't trust it to be run separately.

Cheers,
_

yeye_olive
14th December 2015, 13:05
QtConcurrent::run() might be a bit weird to use when the function generates a result (usage of the QFuture API).
I concede that other QtConcurrent operations have a complicated way of returning results, but QtConcurrent::run() is actually fairly simple. Just set up a QFutureWatcher. When it emits finished(), you can immediately recover the result by calling result(). This is as simple as an asynchronous API can be (well, maybe a signal finished(T result) would be even simpler). A QThread-based solution will end up with a similar interface.


One also needs to be aware that the number of threads is limited, especially when using the overload that does not take a thread pool but uses the global instance.
Sure, but unless fine-grained control over the threads is required (which does not seem to be a primary concern of the OP), it makes sense to let QtConcurrent adapt the number of concurrent jobs to the actual capacity of the system.


And at least in one occasion I had a task not run in a separate thread. Not sure if that was a bug or something like work-stealing in case of an overloaded thread pool, I don't trust it to be run separately.
This probably is a bug; the documentation specifically mentions that the function is run in a separate thread.

In summary, this looks to me like the standard use case for QtConcurrent::run(): the OP just needs a high-level, concise API to run a task in a separate thread, and trusts the platform with the details of job management and scheduling.

artt
14th December 2015, 15:04
I think maybe it is better to convert my console(main.cpp) file with function definition in widget(main.cpp), or just simply copy from one to another as thelast require additional form file - as it is inevident that definition in another cpp would be workable
in main.cpp (how can i include another cpp to main.cpp, as I do it with filewalker.h--if I include filewalker.h with function declaration - do another cpp know where to find its definition or is it present in the whole?).
About this pattern of code that should be present probably in Widget file:


connect(myButton, SIGNAL(clicked()), SLOT(runMyFunctionInAnotherThread()));
...
void myFunction() {
// This function is not meant to be run in the GUI thread
}
...
void MyClass::runMyFunctionInAnotherThread() {
QtConcurrent::run(myFunction);
}

As I understood -- MyClass shoud some kind of Qthread(if I use this threadclass) and its MyClass.h should be included in Widgetfile.
"myFunction()" -- should be some kind as Filewalker::writexmltofile() definition?
And void MyClass::runMyFunctionInAnotherThread() should use MyClass::startthread() when run() found in MyClass declaration.
Where is SLOT signature here? Or it should not be declared as slot in the same file where is connect() statement? Where is 3-rd - receiving object - argument here? "this" or so?

anda_skoa
14th December 2015, 16:53
I concede that other QtConcurrent operations have a complicated way of returning results, but QtConcurrent::run() is actually fairly simple. Just set up a QFutureWatcher. When it emits finished(), you can immediately recover the result by calling result(). This is as simple as an asynchronous API can be (well, maybe a signal finished(T result) would be even simpler). A QThread-based solution will end up with a similar interface.

I generally agree, but you have to know that there is QFutureWatcher and the API is a bit uncommon, even for experienced C++ developers.
But since the OP even has difficulties with basic C++ such as heap allocation or header/source file splits, I have my doubts the QtConcurrent::run() would be understandable.



Sure, but unless fine-grained control over the threads is required (which does not seem to be a primary concern of the OP), it makes sense to let QtConcurrent adapt the number of concurrent jobs to the actual capacity of the system.

Well, thread pool based tasks should be non-blocking (CPU bound), not sure if that is the case of the tasks the OP wants to run.



This probably is a bug; the documentation specifically mentions that the function is run in a separate thread.

Yes, probably, or different in Qt4 which I used at that time.

Cheers,
_

artt
15th December 2015, 01:04
I tried to do more simply: I created widget project and launched such code in main method and renamed main.cpp(in filewalker) to Filewalker.cpp. And after launching such code --


#include <QApplication>
#include <QVBoxLayout>
#include <QSlider>
#include <QSpinBox>
#include <QPushButton>
#include <QLabel>
#include <QFileInfo>
#include "Filewalker.h"
int main(int argc, char *argv[])
{
Filewalker f;// no matching function for call to 'Filewalker::Filewalker()' -- is there no default constructor for it?
//Just candidates are: Filewalker::Filewalker(long int, QString, QString); and Filewalker::Filewalker(const Filewalker&)
QApplication app(argc, argv);
QWidget window;
//QWidget *window = new QWidget;
window.setWindowTitle("File Indexer");
QPushButton *indexate = new QPushButton("&Indexate Files");
QPushButton *writexml = new QPushButton("&WriteXMLtoFile");
QPushButton *readxml = new QPushButton("&ReadXMLfromFile");
QPushButton *render = new QPushButton("&RenderDirectly");
QLabel *label1 = new QLabel();
QLabel *label2 = new QLabel();
QPushButton *search = new QPushButton("&Search file by name");
QObject::connect(indexate, SIGNAL(clicked()),&f, SLOT(Filewalker::walk("C:\\C"))); //no matching function for call to //'QObject::connect(QPushButton*&, const char*, Filewalker&, const char*)' -- what const char* means especially in the last //case, in the first one -- clicked() seams to be normal signal for SIGNAL. How should I describe slot here. Or it is the result of Q_Object macro despite the error seems to be another in such case.
QVBoxLayout *layout = new QVBoxLayout();
layout->addWidget(indexate);
layout->addWidget(writexml);
layout->addWidget(readxml);
layout->addWidget(render);
layout->addWidget(label1);
layout->addWidget(label2);
layout->addWidget(search);
window.setLayout(layout);
window.show();
return app.exec();
}


In the first one I should use not Filealker but Lister class for slot functions such as indexate, writetoxml, so filewalker should be just for objects. And Lister should have default constructor as I initialized it - but without no declared constructor.
If I really need to inherite QObject and include Q_OBJECT macro should I rename such main.cpp in widget..cpp (and delete main() declaration and its brackets) what should I include in another main.cpp method --as In molketin there is just sample of dialog.h , dialog.cpp --ot I should obligatorty include button, windows, labels and connect in main() method??

anda_skoa
15th December 2015, 10:12
Filewalker f;// no matching function for call to 'Filewalker::Filewalker()' -- is there no default constructor for it?
//Just candidates are: Filewalker::Filewalker(long int, QString, QString); and Filewalker::Filewalker(const Filewalker&)

If the compiler says there is no argument-less constructor then it is very likely right.
Check your class declaration.



QObject::connect(indexate, SIGNAL(clicked()),&f, SLOT(Filewalker::walk("C:\\C"))); //no matching function for call to //'QObject::connect(QPushButton*&, const char*, Filewalker&, const char*)'

Is "f" an object of a class derived from QObject. Does it have the Q_OBJECT macro.
Also SLOT(), like SIGNAL(), takes the name of a function and its arguments. Since the signal does not have any arguments that it could pass on, the slot has no arguments either.
So a valid SLOT() content could look like this:


QObject::connect(indexate, SIGNAL(clicked()),&f, SLOT(someSlot()));




-- what const char* means especially in the last //case, in the first one -- clicked() seams to be normal signal for SIGNAL.

SIGNAL() and SLOT() are macros that convert their arguments into const char*, the type a string literal has in C and C++.



In the first one I should use not Filealker but Lister class for slot functions such as indexate, writetoxml, so filewalker should be just for objects. And Lister should have default constructor as I initialized it - but without no declared constructor.

I am afraid I don't know what you mean with the first part, but yes, a class without any declared constructor has a default constructor.



If I really need to inherite QObject and include Q_OBJECT macro should I rename such main.cpp in widget..cpp (and delete main() declaration and its brackets) what should I include in another main.cpp method --as In molketin there is just sample of dialog.h , dialog.cpp --ot I should obligatorty include button, windows, labels and connect in main() method??

Again not sure if I interpret this correctly, but yes, it makes sense to create a widget class that contains the UI building and then just instantiate it in main().

Cheers,
_

artt
15th December 2015, 18:10
What do "someslot" should look like? I defined the Filewalker::walk() (as a function for indexation) as public slot in Filewalker.h - is it not enough?? And I think that all slots like walk(), writetoxmlfile() and qlist <filewalker*> should be put in Lister as class with default constructor (is it possible in such way to use class Lister: public QObject) and Filewalker as class just with fields. So I would put &f as the reference to Lister object. Then how to use UI Widget class just to put the code from current main () to some kind as class guis: public qwidget? Should I do some modification of automatic shaped .ui form file?

d_stranz
15th December 2015, 19:46
Artt - I realize that you may be a skilled Java programmer, but it is obvious from your questions that you do not know much about either C++ or Qt. You are trying to run before you even know how to crawl.

Qt comes with many, many C++ example programs to help you learn all aspects of Qt. Many of the questions you are asking could be answered if you studied the examples and learned from them. Right now, you are asking so many questions which are so confused that it is almost impossible to know where to start to answer them.

So open Qt Creator, click on the Welcome page and look at the Examples or the "Getting Started Programming with Qt Widgets" Tutorial. I think you will find it more helpful than trying to learn C++ and Qt programming from us.

artt
15th December 2015, 22:22
Yes it is my first programm in Qt, despite in Java I have just several ones, but is more competent in it and this language is more light to learn indeed.
I have read somewhere, that you should learn C++, but in Qt just read the documentation.
So here I want to try to do relative complex widget, in one thread, then if succesful then I will do it in multi-thread.
So what I would not read in documentation and examples-- can I absolve of .ui file, can it be blank, should i make some modification of it due the specific of my current task. Then could I use in GUI Qt project just one file for example Filewalker.cpp and call its widget realization in its main()?? Why to do another file for just main()?
//And I do not know why when I opened last yesterday project in Qtcreator - I see grey(disabled) menu of Qtcreator - and I could not activate it anyway?

Added after 36 minutes:

If I modified the Lister.h file by subclassing QObject and transferring slots from Filewalker.h in such way:


#ifndef LISTER_H
#define LISTER_H
#include <QObject>
#include "Filewalker.h"
class Lister : public QObject
{

Q_OBJECT
public:
public: Lister (QObject* parent = 0): QObject(parent){} //By adding such constructor errors not disappear --
static QList <Filewalker*> listed;
//static QTextStream cout(FILE * fileHandle);
public slots:
static void walk(QString path0);
static void writexmlfile(QString path1);
static void readxmlfile();
static void searchname();
};
#endif

I got such error in "upper" main() (when also there substituting Filewalker for Lister) --
In function `Lister':
undefined reference to `vtable
In function `~Lister':
undefined reference to `vtable
//As looking at this pattern (one of the first in Google) http://www.java2s.com/Code/Cpp/Qt/extendsQWidget.htm
it is very close to mine:
I have also Lister.h, FileWalker.cpp (can call also Lister.cpp) with slots definition, and main() with connect statement so --the
issue know is in constructor and destructor in my Lister.h definition, should it subclass Qobject or QWidget, and how to
describe correctly constructor and destructor for it to free of this 2 same errors?
So here I did not have even no example -- as I have it--despite the errors are present.
//And why such code the same in structure of extending QWidget do not work in my case, despite in
http://www.java2s.com/Code/Cpp/Qt/extendsQWidget.htm - probably works


#ifndef LISTER_H
#define LISTER_H
#include <QWidget>
#include "Filewalker.h"
class Lister : public QWidget
{

Q_OBJECT
public: Lister (QWidget *parent = 0 );
static QList <Filewalker*> listed;
//static QTextStream cout(FILE * fileHandle);
public slots:
static void walk(QString path0);
static void writexmlfile(QString path1);
static void readxmlfile();
static void searchname();
};
#endif

After initializing the Lister in main() in such way:


QApplication app(argc, argv);
QWidget window;
//QWidget *window = new QWidget;
window.setWindowTitle("File Indexer");
Lister f(QWidget *window = 0);

I got error about connect:
no matching function for call to 'QObject::connect(QPushButton*&, const char*, Lister (*)(QWidget*), const char*)'
candidates are: static bool QObject::connect(const QObject*, const char*, const QObject*, const char*, Qt::ConnectionType)..etc -- so I understand that I need correct placing of receiving object despite it is like as in examples from java2s, or to eradication of vtable error...

anda_skoa
15th December 2015, 23:34
What do "someslot" should look like? I defined the Filewalker::walk() (as a function for indexation) as public slot in Filewalker.h - is it not enough??

Yes, that is enough.



And I think that all slots like walk(), writetoxmlfile() and qlist <filewalker*> should be put in Lister

That would be ok as well.



as class with default constructor

Type of constructor doesn't matter at all, no difference to Java.



(is it possible in such way to use class Lister: public QObject) and Filewalker as class just with fields. So I would put &f as the reference to Lister object.

Sure, why not.



undefined reference to `vtable

Make sure that the header for Lister is in the HEADERS variable in your .pro file and re-run qmake.

Cheers,
_

artt
16th December 2015, 00:39
Untill now the 2 headers were absent as there is 2 examples of new Lister=Filewalker combination (nested meanwhile so last one jhave no such headers as Filewalkers.cpp with definitions of slots). But after updating it and quiting-opening Qtcraetor -- the Build-Debug menu is inactive again - so I cannot check with new conditions.
Here I provid my current pro file:


QT += core gui

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = Filewalker2
TEMPLATE = app


SOURCES += main.cpp Filewalker.cpp filewalker2.cpp

HEADERS += filewalker2.h Lister.h Filewalker.h


FORMS += filewalker2.ui

The filewalker2.h and filewalker2.cpp were created during the creation of project so could I
delete them, how they influence the my native files? Maybe there is some bad interaction?

#include "filewalker2.h"
#include "ui_filewalker2.h"

Filewalker2::Filewalker2(QWidget *parent) :
QWidget(parent),
ui(new Ui::Filewalker2)
{
ui->setupUi(this);
}

Filewalker2::~Filewalker2()
{
delete ui;
}

and header:
#ifndef FILEWALKER2_H
#define FILEWALKER2_H

#include <QWidget>

namespace Ui {
class Filewalker2;
}

class Filewalker2 : public QWidget
{
Q_OBJECT

public:
explicit Filewalker2(QWidget *parent = 0);
~Filewalker2();

private:
Ui::Filewalker2 *ui;
};

#endif // FILEWALKER2_H

anda_skoa
16th December 2015, 09:19
If you don't need these files, then of course you can delete them if you also remove their name occurences from the .pro file.

Cheers,
_

artt
16th December 2015, 12:58
So why build-debug menu is inactive? Why I should close and open Qtcreator - and it doesnt help. Yesterday -- very different manipulation lead to some results, but why to absolve this problem in once?

Can I also delete filewalker2.ui form file?

anda_skoa
16th December 2015, 13:04
So why build-debug menu is inactive?

Maybe the project is not configured?
See the project button on the left hand side.



Can I also delete filewalker2.ui form file?
If it is not used, sure.

Cheers,
_

artt
16th December 2015, 17:38
As far as I remember -- the Project tab on left side was also ianctive during inactivity of Build-Debug menu.
But it changed to it after I closed and opened Qtcraetor -so do Qtcreator lost the configuration in such way?
And why I can delete ui, h., cpp default automatic setting - I thought it define some basic requirements for Qwidget etc...

anda_skoa
16th December 2015, 19:01
And why I can delete ui, h., cpp default automatic setting - I thought it define some basic requirements for Qwidget etc...
For someone who claims to have been developing software before, in any language, that is a pretty strange question.

A file not being used is a file not needed.

Cheers,
_

artt
17th December 2015, 00:25
Now again interesting problem -
after updating headers yesterday and
instantiating Lister in main():


QApplication app(argc, argv);
QWidget window;
window.setWindowTitle("File Indexer");
Lister f;

I got such error:
undefined reference to `Lister::Lister(QWidget*)';
when constructor is of such kind:


class Lister : public QWidget
{

Q_OBJECT
public: Lister (QWidget *parent = 0 );
What the reason of it --
now all headers are included, as source files?
How define correctly, as the link provide exactly such solution despite it doesnot works here.

anda_skoa
17th December 2015, 08:30
I got such error:
undefined reference to `Lister::Lister(QWidget*)';
when constructor is of such kind:


class Lister : public QWidget
{

Q_OBJECT
public: Lister (QWidget *parent = 0 );
What the reason of it --

Do you have the constructors definition/implementation somewhere?
E.g. in the lister source file?

Cheers,
_

artt
17th December 2015, 10:27
This is the implementation of Constructor of Lister in main ():


QApplication app(argc, argv);
QWidget window;
window.setWindowTitle("File Indexer");
Lister f;

It is almost the same as in link from java2s example:
What definition or implementaion of Lister constructor should look like? In Lister.cpp (in my case Filewalker.cpp, despite the change of name inprobably matters)

anda_skoa
17th December 2015, 12:15
This is the implementation of Constructor of Lister in main ():


QApplication app(argc, argv);
QWidget window;
window.setWindowTitle("File Indexer");
Lister f;


That code does not show the implementation of the constructor of Lister.
It shows the instantiation of three objects and a method call on one of these objects.



What definition or implementaion of Lister constructor should look like?
Like any other method its signature needs to match the signature of its declaration.
What you do in the function body obviously depends on what that class needs to do in the constructor.

Cheers,
_

artt
17th December 2015, 18:42
class Lister : public QWidget
{

Q_OBJECT
public: Lister (QWidget *parent = 0 );
is it not the same as Lister::Lister(QWidget *parent = 0) in Lister.cpp?
What is Lister (QWidget *parent = 0 )?
In the example http://www.java2s.com/Code/Cpp/Qt/extendsQWidget.htm you see the same definition of Constructor
despite with 2 arguments. But there is no Circlebar::Circlebar...in circlebar.cpp - so I cannot copy this example for that my compiler says in the last case.

anda_skoa
17th December 2015, 19:26
class Lister : public QWidget
{

Q_OBJECT
public: Lister (QWidget *parent = 0 );


Yes, you've already shown the declaration


is it not the same as Lister::Lister(QWidget *parent = 0) in Lister.cpp?

No, that is a non-line (not in the header) definition, although it should have the "= 0" part, but the compiler will complain about that anyway.



What is Lister (QWidget *parent = 0 )?

That depends on how the code after that looks like.
If the ? is a ; then
- In a class called "Lister" this would be the declaration of a constructor.
- In a class called something else, this would be the declaration of a method.
- Outside a class that would be the declaration of a function.

If the ? is a { then
- In a class called "Lister" this would be the declaration and inline definition of a constructor.
- In a class called something else, this would be the declaration and inline definition of a method.
- Outside a class that would be the declaration and inline definition of a function.



In the example http://www.java2s.com/Code/Cpp/Qt/extendsQWidget.htm you see the same definition of Constructor

Yes, indeed.



despite with 2 arguments.

Yes, constructors can have any number of arguments



But there is no Circlebar::Circlebar...in circlebar.cpp

Of course, right there in the link you've provided, first thing after the includes.

Cheers,
_

artt
17th December 2015, 19:40
Sorry, I automatically overlooked it as I thought it is without need.
But my lister is in fact the void class except static slot functions and static Qlist listed variable, so
I think I should probably use such examples doc.qt.io/qt-4.8/designer-using-a-ui-file.html
http://stackoverflow.com/questions/10591059/meaning-of-qwidget-parent-0-in-constructor-myclassqwidget-parent-0
Despite I cannot override the inactive build-debug menu in Qtcreator...So it is difficult to check in time.

anda_skoa
17th December 2015, 20:21
But my lister is in fact the void class except static slot functions and static Qlist listed variable, so

Then you don't need a constructor.

But I thought you wanted slots in that class?



I think I should probably use such examples doc.qt.io/qt-4.8/designer-using-a-ui-file.html

How is this relevant here?

Cheers,
_

artt
17th December 2015, 20:40
No really the java2s example is very appropriate:


Lister::Lister (QWidget *parent) : QWidget( parent )
{
}
It works
But now the issue is in connect statement that works for
QObject::connect(indexate, SIGNAL(clicked()),&f,SLOT(readxmlfile()));
But the next function despite finely compiled and run is not active - e.i. its button--end this connect statement is underlained by red wavy line--it was happened the several last days with red line
QObject::connect(indexate, SIGNAL(clicked()),&f,SLOT(walk("C:\\C")));
I change to another folder -the same...

d_stranz
17th December 2015, 23:22
Artt, I'll say it again: Clearly you do not understand enough of the basics of C++ to write the program you are trying to write. Every question you ask shows that you do not understand.

C++ is not java, even though the syntax is similar. In C++, the definition of a class is usually divided among two files: a header file, usually with a ".h" or ".hpp" suffix, and an implementation file, usually with a ".cpp" suffix. In the header file, the name of the class, its inheritance, and any member variables and functions are declared, but not very often implemented. So, in your case:



class Lister : public QWidget
{

Q_OBJECT
public: Lister (QWidget *parent = 0 );


This code "declares" that there is a class called "Lister", that it publicly "inherits" from another class called "QWidget", and "declares" that there is a constructor method ("Lister()") that takes an optional argument of type "pointer to QWidget". If the argument is not provided in the code that uses the Lister class, the compiler is told to insert a "0" (null pointer) to be used instead. The Q_OBJECT macro inserts some macro code for Qt's meta-object system which you do not need to know anything about.

This code does not implement Lister, it simply makes the declarations I have explained above. In order for the Lister class to be used in your program, you have to define the implementation of the constructor and any other methods in the cpp file:



// Lister.cpp

#include "Lister.h"

Lister::Lister (QWidget *parent) : QWidget( parent )
{
}


In addition, Lister.cpp must be compiled and linked into your program, otherwise the linker will tell you that there is an undefined reference to it. It isn't enough just to have the file laying on your disk drive. You have to add it to the project file, otherwise nothing will happen with it and you will get linker errors.

I am also convinced that you do not understand the meaning of the C++ keyword "static" when applied to methods of a class. It makes no sense at all to have a class whose methods are all declared "static" but which also contains a public constructor and non-static member variables.

So please. get yourself a C++ textbook and learn how the language works. C++ is not java, and very little of what you know about java can be applied to C++.

artt
18th December 2015, 01:09
It makes no sense at all to have a class whose methods are all declared "static" but which also contains a public constructor and non-static member variables.
So please. get yourself a C++ textbook and learn how the language works. C++ is not java, and very little of what you know about java can be applied to C++
Should I make this methods non-static? Why? There are no non-static variable and methods in Lister, just static --despite all of them is thransfered from Filewalker - that I made - in course of events -- just for instances. In this situation I just copied the constructor infos from java2s examples no more.
And I have read a lot of books - this my first big project either in C++ and Qt.
And this project works almost except I should add the Textedit for rendering xml and Qlabel for displaying the result of searchbyname.
And of course- then realize with Qthreads-- As a results it will help me very well in practical familiarization with Qt and C++.
Everything else is known for me at this moment. Yet about 10 days ago I did not used never .h
files but I know now that I could put several class headers in one .h file. But why not use public constructor if there is example in java2s and static methods I do not know - what is your idea of design?

Added after 17 minutes:

The last question was very simple - do SLOT(function("path")) do not work correctly as simmply SLOT(function()) - this is just about Qt

anda_skoa
18th December 2015, 09:20
But now the issue is in connect statement that works for
QObject::connect(indexate, SIGNAL(clicked()),&f,SLOT(readxmlfile()));

Is "indexate" a pointer to a QObject derived class?
Does it have a clicked() signal?
Is &f a pointer to a QObject derived class?
Does it have a readxmlfile() slot?




QObject::connect(indexate, SIGNAL(clicked()),&f,SLOT(walk("C:\\C")));

That is not a valid SLOT macro content.

As I explained earlier, the SIGNAL and SLOT macros contain method names and, if applicable, argument types.
"C:\\C" is not a C++ type, it is a string literal.

Cheers,
_

artt
18th December 2015, 10:01
Is "indexate" a pointer to a QObject derived class?
Does it have a clicked() signal?
Is &f a pointer to a QObject derived class?
Does it have a readxmlfile() slot?
That is not a valid SLOT macro content.
As I explained earlier, the SIGNAL and SLOT macros contain method names and, if applicable, argument types.
"C:\\C" is not a C type, it is a string literal.
Cheers,
_ So It should work like SLOT(walk()) but do not work like SLOT(walk("C:\C")). Is it impossible to work with last variant anyway? Should I include the dialog for choosing appropriate folder in walk()? But there is some moments when you need to use method with explicit definition of path as argument...

anda_skoa
18th December 2015, 10:37
So It should work like SLOT(walk()) but do not work like SLOT(walk("C:\C")).

Yes, "..." is a string literal, not a type name.



Is it impossible to work with last variant anyway?

Yes, as explained at least twice already, the SLOT macros needs a method name and, if necessary, the types of the arguments.



Should I include the dialog for choosing appropriate folder in walk()?

If that is what you want to do, why not.



But there is some moments when you need to use method with explicit definition of path as argument...
Then you call the method with the path.
Really the same as in Java.

Cheers,
_

artt
18th December 2015, 13:45
"Then you call the method with the path." - so how to call such method coorectly?
If walk("C:\C") is the string literal (or to exactly "C:\C")) - what kind of type is walk() as it is method with void return type.

anda_skoa
18th December 2015, 14:36
"Then you call the method with the path." - so how to call such method coorectly?
If walk("C:\C") is the string literal (or to exactly "C:\C")) - what kind of type is walk() as it is method with void return type.

You are mixing things up.
Calling


walk("C:\\C")

is fine.

Just putting that into a SLOT macro is not since that requires a slot signature.

Cheers,
_

artt
18th December 2015, 14:42
Should I put in such manner -
QObject::connect(indexate, SIGNAL(clicked()),&f,walk("C:\\C"))?

anda_skoa
18th December 2015, 15:56
No.

Cheers,
_

artt
18th December 2015, 18:23
QString p="C:\\C";
QObject::connect(indexate, SIGNAL(clicked()),&f,SLOT (walk(p)));
It is simple solution, and the red wavy underline disappear even before compilation (is inactive again).

artt
19th December 2015, 00:00
d_trans I do not understand do you think I am right in connect statement as I cannot to check as I need to manipulate Qtcreator to make build and debug available.
But i have similar situation yet about putting this connect statement in single thread:
Here is my solution but I have two issues: the first is how to define the run() of Qthread as a slot?
Here is my approach:


I create Thread.h for several thread headers: here is for the first one for indexate button and walk() method.
#ifndef ITHREAD_H
#define ITHREAD_H
#include <QWidget>
#include "Filewalker.h"
#include "Lister.h"
class IThread : public QThread
{
Q_OBJECT
public slots:
void run();
};
#endif
Then define run() in Lister.cpp without defining IThread constructor.
void IThread::run()
{
Lister::walk(QString);
}
Maybe I should define run in new .cpp as walk() is also defined here.
Then in main () I initialize
Ithread variable, and start it. But to put it in connect I found just one wayout to assign ITread.start() to QObject instance by analogy to Java.
IThread A;
QObject pp=A.start();
QObject::connect(indexate, SIGNAL(clicked()),&f,SLOT (pp)); //It is underlined in red from the left of line that probably is not //correct as well as two previous lines. As Ithread::run() in another file despite the red line appera even I click by mouse any new line before any insertion in Lister.cpp

Again I cannot check as I have no time to correct Qtcreator(and everytime), but I see it just in this way, especially starting Ithread???

d_stranz
19th December 2015, 00:05
It is simple solution

AND STILL INCORRECT

The SIGNAL() and SLOT() macros each take as arguments the signature of the methods they will invoke, with the return type always being implicitly understood to be "void".

Examples of correct SIGNAL() or SLOT() syntax are:



SIGNAL( myMethod1() ) // a method that takes no parameters and returns void.
SIGNAL( myMethod2( int ) ) // a method that takes an int parameter type
SIGNAL( myMethod3( int, const QString & ) ) // a method that takes two parameters, one an int, the second a const QString reference


Examples of incorrect syntax are:



SIGNAL( myMethod2( myVariable ) ) // "myVariable" is the name of a variable, not a type
SIGNAL( myMethod3( 4, "some string" ) ) // "4" and "some string" are literals, not types


(Other examples of incorrect syntax include every "solution" you have posted).

Furthermore, you cannot connect a signal with fewer parameters to a slot with more parameters unless the slot's parameters have default values. You cannot connect a signal to a slot with different parameter types. You can connect a signal with more parameters to a slot with fewer parameters; the extra parameters from the signal will be ignored.



connect( myInstance1, SIGNAL( myMethod1() ), myInstance2, SLOT( myMethod2( int ) ) ) // error - no match for int slot parameter
connect( myInstance1, SIGNAL( myMethod1( int ) ), myInstance2, SLOT( myMethod2() ) ) // OK; int signal parameter is ignored
connect( myInstance1, SIGNAL( myMethod1( int, const QString & ) ), myInstance2, SLOT( myMethod2( int, double ) ) ) // error - parameter types don't match



QObject::connect(indexate, SIGNAL(clicked()),&f,SLOT (pp));

Wrong - see example #1 of incorrect syntax above. "pp" is not a type, it is the name of a variable. And also wrong because the signal clicked() has no parameters. And wrong one more time because "pp" is not the signature of a slot defined in the class reference by the receiver "&f".

anda_skoa
19th December 2015, 10:16
Here is my solution but I have two issues: the first is how to define the run() of Qthread as a slot?

And why would you want run() as a slot?
You know that is the method that is executed by the worker thread, right? Just like in Java.


IThread A;
QObject pp=A.start();

That won't compile because QThrad::start() doesn't return anything.
You know, just like in Java.

It starts the thread which will then execute the run() method.
You know, just like in Java.

Cheers,
_

artt
19th December 2015, 12:05
Should I make start() as a slot? Or to be correctly: Should I made some thirdlevel Wrapper method for walk as slot? That is place Lister::walk() in run(), then A.start(), and them Someclass(Lister also f.e.)::walkwiththread() as slot, where I would put A.start()?// should I use event in my thread to correctly interact with Mainthread? Some kind of post...()?

anda_skoa
19th December 2015, 14:27
Should I make start() as a slot?

QThread::start() is a slot.


Or to be correctly: Should I made some thirdlevel Wrapper method for walk as slot? That is place Lister::walk() in run(), then A.start(), and them Someclass(Lister also f.e.)::walkwiththread() as slot, where I would put A.start()?// should I use event in my thread to correctly interact with Mainthread? Some kind of post...()?
I don't have a clue what you mean.

But if you meant creating a slot that will call walk with an argument, then yes.

Cheers,
_

artt
19th December 2015, 15:28
I did not understand the first of your last statements? Is it some constatation(affirmation)? And I mean to make public slot: void Lister::walkwiththread() { A.start()}, when void IThread::run { Lister::walk(QString)}...
/"Yes, that's a workable direction" -- is it not too much? Maybe there would be some cycle -- lister method --ithreadmethod--starting
ithreadmethod--another lister method -- could it work? -- as I am really very tired of inactive Build-Debug menu

anda_skoa
19th December 2015, 15:40
Yes, that's a workable direction.

Cheers,
_

artt
20th December 2015, 02:06
If I define IThread::run() in Lister.cpp with definition of Lister::walk(QString path0), lower in the same file I got such errors with 2 modifications - should I define these 2 methods in different files or in inverse order?


1. void IThread::run()
{
static void Lister::walk(QString path0);
}

ERRROR:invalid use of qualified-name 'Lister::walk'

2.
void IThread::run()
{
Lister::walk(QString);
}

ERROR:expected primary-expression before ')' token

There is also run-time error with the argument of walk(pp) - so should I understand that I need just walk()?
QString p="C:\\C";
Object::connect: No such slot Lister::walk(pp) in ..\Filewalker2\main.cpp:32

anda_skoa
20th December 2015, 11:28
1. void IThread::run()
{
static void Lister::walk(QString path0);
}

ERRROR:invalid use of qualified-name 'Lister::walk'

2.
void IThread::run()
{
Lister::walk(QString);
}

ERROR:expected primary-expression before ')' token


The first one doesn't make sense. You want to call a function, not declare one.

The second one is a function call, but you are passing a type as the argument instead of a value.
Since that would not work in Java either I have now serious doubts that you have even programmed a single line in Java as well.



There is also run-time error with the argument of walk(pp) - so should I understand that I need just walk()?
QString p="C:\\C";
Object::connect: No such slot Lister::walk(pp) in ..\Filewalker2\main.cpp:32

That has been already been answered several times.

Cheers,
_

artt
20th December 2015, 15:06
1. You provided such radical thoughts: it is very big blame to write I do not write a line in a Java
despite it seems is thirdly light than Qt for such project. And of course there were attempts and errors.
After providing arguments:
QString path0="C:\\C";
for Lister::walk(path0) it works (and after putting A->start() on the heap).
But walkwiththread() works with small folders -- for example with 28 entities (shows the properties of 28 files) - but when with C:\Windows, it is inactive. And in debugger mode - when clicking on indexate() button for running walkwiththread()
I got the instant message: "Thread 1 of Group 1 finished" (in one of status bar of Qtcreator tabs), then clicking the second time "Thread 2 of Group 1 finished", etc. So maybe I need some another wrapper or additional method for launching
time-consuming thread - as 28 entities(or 19, or 5) renders instantly??
Anyway in both cases when seeing Debugger launched in console - I see at first the familiar message about absence of 22 libraries--but it display after the list of results with small folders..
And I put in .pro file: Qt+= gui core thread concurrent or ... threads concucrrent --despite I cannot found the reference about it in 2 my read books, but there is reference for "concurrent" in Blanchette despite it is another Qtconcurrent class.
So partially such scheme works..
And what about walk(pp) -- even in Auto-fill mode of Qtcreator I see SLOT(walk(QString)) - so the message in some kind the error - as such slot is present. Or should I to provide walk() without arguments or make clicked(pp) with arguments.

anda_skoa
20th December 2015, 15:46
1. You provided such radical thoughts: it is very big blame to write I do not write a line in a Java

Well, that was based on the failure to understand the difference between a type and a variable.
Because Java has exactly the same terminology for these concepts.

E.g.


class Main
{
static void main(String[] args)
{
String pp;
}
};

String is a type, pp is a variable of type String. pp is not a type.
In Java doing this would also not compile


void walk(String path)
{
}

void doWalk()
{
walk(String);
}

Again, because walk() expects an argument of type String, not the type itself.

Since half of the thread deals with you not understanding these simple facts for C++, I could only conclude that you don't understand them in Java either.



but when with C:\Windows, it is inactive.

What does that even mean "inactive"?
Does the method not execute depending on what you pass as its argument?



And I put in .pro file: Qt+= gui core thread concurrent

I am pretty sure "thread" is not a name for a Qt module.
"gui", "core" and "concurrent" are, the latter being needed for use of QtConcurrent, not for QThread.
QThread is part of QtCore.



or ... threads concucrrent --despite I cannot found the reference about it in 2 my read books, but there is reference for "concurrent" in Blanchette despite it is another Qtconcurrent class.

QtConcurrent is a namespace for functions that primarily deal with parallel algorithms, such as invoking the same function on all elements in a container, for multiple container entries concurrently.



And what about walk(pp) -- even in Auto-fill mode of Qtcreator I see SLOT(walk(QString))

So far your code indicated that pp was a variable of type QString, not a type called pp.
Do you have a class called "pp"?
Is the slot taking an argument of type "pp"?

Cheers,
_

artt
20th December 2015, 17:57
Of course, QString pp="C:\\C" means that pp is variable of Qstring. But I cannot put simply SLOT(walk(Qstring)), as the folder would not be defined so I put there concrete variable pp. Oh, in the course of writing these comment, I guessed maybe I need
to put Lister::walk(QString) as Lister::walk(pp), or even put pp("C:\\C") as a argument in declaration of slot public Lister { slot: walk(QString pp). } So it happened to be some euristics. In some way it should works.
Anyway - in thread environment this issue should be absent- but QThread do not work with processing big folder - taht is issue now. So I do undestand I need some tool for time-consuming for time-sonsuming thread.

anda_skoa
20th December 2015, 18:14
Of course, QString pp="C:\\C" means that pp is variable of Qstring.

Good that we could clarify that.



But I cannot put simply SLOT(walk(Qstring)), as the folder would not be defined so I put there concrete variable pp.

Explained several times already.



Anyway - in thread environment this issue should be absent- but QThread do not work with processing big folder - taht is issue now.

A thread is just a parallel execution context.
It doesn't matter to the thread how big a folder is.



So I do undestand I need some tool for time-consuming for time-sonsuming thread.
No idea what you mean.

Cheers,
_

d_stranz
20th December 2015, 18:48
11582

I'm beaming out of here.

artt
20th December 2015, 20:26
I do not really understand you facepalm, and suspects of java code-- the only I copied from the net was exactly filewalker pattern (yet in qt).
Anyway eveything almost works
-- "is inactive" -- when I press indexate button and walkerwiththread() process C:\\Document and Settings (wriitten directly in Lister.cpp)-- i got nothing in console.
If it processes C:\\C (wriitten directly in Lister.cpp) it instantly render 28 results for other folder.
Maybe not everything is on heap, and yet in stack as it was at the beginning?
Anyway in both cases -- when Debug started...
I got such lines in console:
Could not load shared library symbols for 22 libraries, e.g. C:\WINDOWS\system32\ntdll.dll.
Use the "info sharedlibrary" command to see the complete listing.
So it happened when my Qfilelistinfo was on the stack.
Then small folders shows:

File:1656 catalog.php C:/includes/admin 4
File:1735 conf.php C:/includes/admin 4
File:1590 custord.php C:/includes/admin 4
File:4256 catalog_products_categories.php C:/includes/admin/sub 4
File:2754 catalog_special.php C:/includes/admin/sub 4
... (Big Folders nothing).
If I click again thread(it shows the thread2, and so on)
I got again
File:1656 catalog.php C:/includes/admin 4
File:1735 conf.php C:/includes/admin 4...
So this "Could not load shared library" appears at the beginning of run, so creation of Qwidget.
Really a very small need sto be done -- and it is really needs some SwingWorker java analogue as it renders instantly, but
in case of C:\Windows it could noty happened as well in the case of whole C:\, or all disks..

anda_skoa
20th December 2015, 21:10
-- "is inactive" -- when I press indexate button and walkerwiththread() process C:\\Document and Settings (wriitten directly in Lister.cpp)-- i got nothing in console.
If it processes C:\\C (wriitten directly in Lister.cpp) it instantly render 28 results for other folder.

And you have equal access rights to both folders?

Have you added addition logging to see what happens?



Maybe not everything is on heap, and yet in stack as it was at the beginning?

We've already determined that this doesn't matter.



Anyway in both cases -- when Debug started...
I got such lines in console:
Could not load shared library symbols for 22 libraries, e.g. C:\WINDOWS\system32\ntdll.dll.
Use the "info sharedlibrary" command to see the complete listing.

Obviously the debugger can't find the debug symbols for these libraries.
Not a problem until you have to debug into them.



Really a very small need sto be done -- and it is really needs some SwingWorker java analogue as it renders instantly

So it works when you run everything from the main thread?

Cheers,
_

artt
20th December 2015, 22:12
No once I put:


QString path0="C:\\includes";
void IThread::run()
{
Lister::walk(path0);
} -- and run it. Then change to:
QString path0="C:\\Windows";
void IThread::run()
{
Lister::walk(path0);
}
and run.
Everything not works, unfortunately...
Excerpts from Qt Assistant:
In practice, the impossibility of using GUI classes in other threads than the main thread can easily be worked around by putting time-consuming operations in a separate worker thread and displaying the results on screen in the main thread when the worker thread is finished.
Maybe I need some additional methods or tools to wait when worker thread made nessesary work, and then return in mainthread-- as I see that workerthread return immediately, it doesnt wait.
I read 2-3 days ago about linking worker thread to main(GUI)thread and as I remember there were mentioned as events as the some method post..() but it is not 100% postevents(), although maybe. Anyway there are also option Qtconcurrent(), despite i am not aware is it applicable for several threads (buttons) along mainthread, and qRunnable.
There is also Mandelbrot and the Blocking Fortune Client example in QtAssistant -despite it is too compicated for me as for now, and I do not need any blocking and mutex, just deblocking-that several buttons could be available in the same time-and main gui would not be non-freezing

Added after 22 minutes:

No once I put:


QString path0="C:\\includes";
void IThread::run()
{
Lister::walk(path0);
} -- and run it. Then change to:
QString path0="C:\\Windows";
void IThread::run()
{
Lister::walk(path0);
}
and run.
Everything not works, unfortunately...
Excerpts from Qt Assistant:
In practice, the impossibility of using GUI classes in other threads than the main thread can easily be worked around by putting time-consuming operations in a separate worker thread and displaying the results on screen in the main thread when the worker thread is finished.
Maybe I need some additional methods or tools to wait when worker thread made nessesary work, and then return in mainthread-- as I see that workerthread return immediately, it doesnt wait.
I read 2-3 days ago about linking worker thread to main(GUI)thread and as I remember there were mentioned as events as the some method post..() but it is not 100% postevents(), although maybe. Anyway there are also option Qtconcurrent(), despite i am not aware is it applicable for several threads (buttons) along mainthread, and qRunnable.
There is also Mandelbrot and the Blocking Fortune Client example in QtAssistant -despite it is too compicated for me as for now, and I do not need any blocking and mutex, just deblocking-that several buttons could be available in the same time-and main gui would not be non-freezing
//Just now I put the folder to path0 variable with about rendered 1000 results, and 3-4 secs. of processing. So it is not instant.
But it actually do not reacts for such meta-directories as C:\Windows, C:\Documenst and Settings or simply the C:\ -- that is fact. You should understand that I change the name of folders directly in the code, and for testing purposes

anda_skoa
20th December 2015, 22:50
Everything not works, unfortunately...

Let me repeat:

Does it work when you have no additional thread?




In practice, the impossibility of using GUI classes in other threads than the main thread can easily be worked around by putting time-consuming operations in a separate worker thread and displaying the results on screen in the main thread when the worker thread is finished.
Maybe I need some additional methods or tools to wait when worker thread made nessesary work, and then return in mainthread-- as I see that workerthread return immediately, it doesnt wait.

If you mean QThread::start() returns immediately, then yes of course, that's the whole point.



I read 2-3 days ago about linking worker thread to main(GUI)thread and as I remember there were mentioned as events as the some method post..() but it is not 100% postevents(), although maybe.

You can use events but using a signal is way easier.
If the thread doesn't have to report progress, then connect to the thread's finished() signal.

Anyway, make sure the program works without threads before making it more complex.

Cheers,
_

artt
21st December 2015, 00:21
Really after putting the modified walk() without args-

QObject::connect(indexate, SIGNAL(clicked()),&f,SLOT (walk()));
the indexate button do not works with big folders as C:\ , C:\Windows, just with small ones (in this instance it seems some infinite loops hapened and my PC switched off-- even so happened --despite before it I cannot copy and past in my whole windows XP along several last hours -- such situation also occures sometimes).
So thread is realized correctly.
So what code be the reason of walk() in connect().
That is probably visible in Debug Mode that shows some missing libraries. It was happened before I configured walk() method simply to console and when list of qfileinfos was at stack.
Anyway connect stament works correctly with small memory consuming examples as readxmlfromfile() [as files is just with several xml entities, written once].
So maybe I need call not Lister f (borrowed in some way from java2s), but Lister* f=new Lister()??

anda_skoa
21st December 2015, 09:02
Really after putting the modified walk() without args-

QObject::connect(indexate, SIGNAL(clicked()),&f,SLOT (walk()));

Yes, that looks ok.



the indexate button do not works with big folders as C:\ , C:\Windows, just with small ones (in this instance it seems some infinite loops hapened and my PC switched off-- even so happened --despite before it I cannot copy and past in my whole windows XP along several last hours -- such situation also occures sometimes).

Whatever that means, it is a clear indicator that you are not yet at the stage where you can consider using a thread.
First you need to get the code working.



So maybe I need call not Lister f (borrowed in some way from java2s), but Lister* f=new Lister()??

That depends on the life time requirements of f.
If it needs to live longer than the scope of where it is created, then it needs to be allocated on the heap or at a higher scope.

Cheers,
_

artt
21st December 2015, 14:01
Here I should tell you that you are wrong.
I compiled as well as with Lister* f=new Lister();
But the result is the same as in case of previous example:
The big folders contents do not render anyway,
but small folder contents render f.e. with QObject::connect(indexate, SIGNAL(clicked()),&f,SLOT (walk()));
File:13 .htaccess C:/includes 4
File:13 .htaccess C:/includes 4
File:13 .htaccess C:/includes 4
...
The big column of such lines and the message in the end of console:
The program finished unexpectedly.
The ... Filewalker.exe crashed.
So the conclusion about thread is incorrect -- exactly in thread the small folder content renders correctly.
So I have any suggestion ...
about infinitive rendering and why big folders do not render.
//But now changing
...SLOT (walkwiththread())) ...
I got
File:13 .htaccess C:/includes 4
File:13 .htaccess C:/includes 4...So the reason of infinitive loop is in
that I should use walk(path0) with arguments -- so it should resolved the issue of signals without args and slot with args -- that is not issue for thread, as it worked 2 days ago.
Anyway the issue of non-rendering of big folders remains.

anda_skoa
21st December 2015, 17:23
Anyway the issue of non-rendering of big folders remains.

Then this needs to be fixed before you can consider parallelizing work with threads.

Obviously the easiest solution would be to use QDirIterator, but for some reason you don't like easy solutions.

Cheers,
_

artt
21st December 2015, 21:36
As the post do not allow atatchmen, here I provided the link for my whole project: http://s000.tinyupload.com/?file_id=84821499628647444433.
If can to see, I would be thankful.
Despite I do not think QIterator would help, despite I would try it, but not today. But when I simply displayed in console not in connect() it worked fine, after I put everything for heap. Regards, artt

yeye_olive
22nd December 2015, 10:15
A quick look at your code convinced me that you aimed far too high for a first C++ project. You have already spent days hacking around and drawing this forum's resources, when you could have made a much more productive use of this time by:

learning C++;
learning Qt, especially by reading the documentation and starting playing with the examples;
building a prototype that does what you want without concurrency;
learning about Qt's concurrency features and the related strengths/pitfalls;
modifying your prototype so that long computations are offloaded to another thread.


I found this gem in your code:

int s=sizeof(Lister::listed);
If you can't see how terrible that is, then you'd better start learning C++.

Please stop allocating everything on the heap. This is C++, not Java.

Oh, and Lister::walk() does not terminate if path0 contains a subdirectory, because it makes a recursive call which traverses path0 again instead of the subdirectory. No wonder it takes too long. Nothing to do with threads, by the way.

anda_skoa
22nd December 2015, 10:42
As the post do not allow atatchmen, here I provided the link for my whole project: http://s000.tinyupload.com/?file_id=84821499628647444433.

The forum does support attachments.

Anyway, yeye_olive already took care of the answer.




Despite I do not think QIterator would help
Well, QDirIterator would help if you want to actually traverse the directory tree.
If you want to be stuck in an endless recursion, then it will not help.

So it really depends on what you want to do.

- If you want to traverse a tree of directories and store information about certain files, then use QDirIterator.

- If you want to send a thread into an endless recursion that will at some point cause the program to crash, then use your code.

Cheers,
_

artt
22nd December 2015, 13:16
What about C++ you want I should learn? I learned about C++ a lot, but without practical application, it is nothing, especially in C++.
You are not correct in some way. Endless recursion happened when I pass walk() as slot in connect(), but when simply call walk() in main() of Lister.cpp it works well. And when I put simply walk() in single thread() in walkwiththread() it doesnt induce infinite loop. But with big folders it really could not stand, but when simply walk() put in Lister::main() it could -- you can even check, and I have write about it 1 or 2 weeks ago.
int s=sizeof(Lister::listed) - maybe it is excess here - but I simply wanted to know the size of listed Qlist, despite it really
return the sizeof Qlist type, despite I hardly conceive about size of Qlist type (what is it? it return always 4), and I need the size of listed as object. There is also such line, seems to be borrowed from my java code where it was used for testing.
Maybe, Qdiriterator should works - as whatsoever purpose did it craeted but here it is said it is slow - http://www.qtcentre.org/threads/57905-Fast-solution-to-list-directories-recursively.
But how should it works here?
Example from QtAssistant -


QDirIterator it("/etc", QDirIterator::Subdirectories);
while (it.hasNext()) {
qDebug() << it.next();

// /etc/.
// /etc/..
// /etc/X11
// /etc/X11/fs
// ...
}
Should I remake for such kind:

QDirIterator it("/etc", QDirIterator::Subdirectories);
while (it.hasNext()) {
if(it.next().fileInfo().isDir())...I need here again the QDirIteratot -- so recursion???
else {
couе<<it.next().fileInfo().fileName ()<<it.next().fileInfo().size ()<<it.next().fileInfo().absolutePath();
}
}

Or maybe I misunderstand how this iterator works? Should it walk every folder recursively by itself - or how absolve the recursion here?
Or I should create whole list of folders?? Then process just files there?

anda_skoa
22nd December 2015, 14:02
Endless recursion happened when I pass walk() as slot in connect(), but when simply call walk() in main() of Lister.cpp it works well.

This is highly unlikely since path0 never changes on recursion, so each recursion processes the same directory over and over again.
So this will always lead to an endless recursion, no matter how you involke the first iteration.



int s=sizeof(Lister::listed) - maybe it is excess here - but I simply wanted to know the size of listed Qlist

QList::size() or QList::count().



return the sizeof Qlist type, despite I hardly conceive about size of Qlist type (what is it? it return always 4)

You are likely on a 32bit machine, where a pointer is 4 bytes (32bits) long.



and I need the size of listed as object

That's the (memory) size of the list object, see above if you want to size as in "number of entries".



Maybe, Qdiriterator should works - as whatsoever purpose did it craeted but here it is said it is slow - http://www.qtcentre.org/threads/57905-Fast-solution-to-list-directories-recursively.

I think the priority should be to make it work and care about fast/slow later.
Do you prefer fast but not working?



Should I remake for such kind:

QDirIterator it("/etc", QDirIterator::Subdirectories);
while (it.hasNext()) {
if(it.next().fileInfo().isDir())...I need here again the QDirIteratot -- so recursion???
else {
couе<<it.next().fileInfo().fileName ()<<it.next().fileInfo().size ()<<it.next().fileInfo().absolutePath();
}
}

Or maybe I misunderstand how this iterator works?

An iterator, a concept also well established in Java, provides a uniform way to linearily traverse a data structure.
The data structure might have tree form, e.g. a map, but the iterator will take care of going up and down the tree.

QDirIterator even follows the Java style iterator pattern that uses "hasNext" and "next" to drive it.
So calling next() multiple times like in your code snippet, will advance the iterator multiple times.

Maybe you want to output the file name, the size and the absolute path from tree different files into one line, maybe not.



Then process just files there?

Well, your code seems to store information about files it finds, so you can just do the same whenever the iterator points to a file.

Cheers,
_

artt
22nd December 2015, 14:23
Sorry - the initial version of walk() was walk(path0), so it was the reason that when I put walk() in connect statement it rendered the same folder as initial path0 was written outside of walk() method, so during the recursion it referred the same folder. So when I simply put walk(path0) to walkwiththread with run() amd start() of Qthread it did not provided the issue.
So even in recursive version of walk(path0) -- the issue is how link correctly SIGNAL(clicked()) and SLOT(walk(path0)) as this pair is with arguments in last case?? Is it possible in theory? despite I could simply put walk(path0) in another void walkwrapper() method -- so it should work in connect, but should recursion be correct -- and I should underline --there were no reference from my part about endless recusrion--despite infinite list of the same folder fileinfos...
And I do not understand if Lister::walk("C:\Windows") [about 25% of C:\ drive] works when called in Lister::main() it renders all infos in console in a several minutes, even faster as it was in Java,
why it could not work in connect(..SLOT(walkwiththread())), as thread is organized correctly by me, and works with small folders -- even with that ones with several thousands of files -- but C:\Windows should have 20-30 thousands ones.

anda_skoa
22nd December 2015, 15:45
the issue is how link correctly SIGNAL(clicked()) and SLOT(walk(path0)) as this pair is with arguments in last case??

SLOT can't reference variable names, as pointed out multiple times in this thread.



Is it possible in theory?

No, as answered multiple times already.



despite I could simply put walk(path0) in another void walkwrapper() method

Yes, as .....


and I should underline --there were no reference from my part about endless recusrion

The endless recursion was evident from the code.



why it could not work in connect(..SLOT(walkwiththread()))

There is no difference from a method's point of view whether it is called in code or via signal/slot.



as thread is organized correctly by me

Well, if you want to make your life complicated and debug a multithreading application instead, go ahead.

Cheers,
_

artt
23rd December 2015, 00:29
You told me eventually that I cannot put SLOT(walk(path0)) even theoretically - but it is easy to solve.
I just put

Lister::walk() {
QString path0="C:\\..."
Lister::walk(path0)
}
But why I get
Could not load shared library symbols for 22 libraries, e.g. C:\WINDOWS\system32\ntdll.dll.
Use the "info sharedlibrary" command to see the complete listing.
Do you need "set solib-search-path" or "set sysroot"?Could not load shared library symbols for C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2180_x-ww_a84f1ff9\comctl32.dll.
Do you need "set solib-search-path" or "set sysroot"?Could not load shared library symbols for C:\WINDOWS\system32\uxtheme.dll.
Do you need "set solib-search-path" or "set sysroot"?Could not load shared library symbols for C:\WINDOWS\system32\MSCTF.dll.
Do you need "set solib-search-path" or "set sysroot"?
What the reason of it.
I will sure use QDirIterator, but why this recursion cannot hadle big folders.
Now it againt do not work directly for Lister::main()
but once it worked (when I put everything on heap ( in other case just 15 results appeared )- now the code is the same ).
And this message should mean some issue that could be solvable???
And then to be worked

artt
23rd December 2015, 17:37
"Could not load shared library symbols for 22 libraries, e.g. C:\WINDOWS\system32\ntdll.dll" -- could it be the reason of this semi-workedness of walk() or it just influences
the debugging process, but no compiling and runnibg of application?

anda_skoa
24th December 2015, 12:19
The debugger just complains about not finding the debugging symbols for certain libraries.
That does not impact the application at all.

Cheers,
_

artt
24th December 2015, 13:03
Your answer about debugger is expected

Added after 14 minutes:

So what about idling the walk() method on big folders? It worked fine with processing at least 60000 files, then complaing about heap memory.
Why C++ cannot overcame the barrier about 20 or something less files, but it could process untill now the folders with several thousands files.
What could be the issue. I think that the experienced programmers should make some suggestion or how to debug it, how find this reason, so when I launching the debugger I get (exceot the message of missing folders) the line, that Filwalker.exe application started....So what happenning at that moments that no message no results I could not got?
So some faillure is at the very beginning of processing, as with some enough big "processable" folders the list of results appearing sequencially.
An If use QDirIterator -- it should probably use the recursion when transforming Qt code to standart C++ during run-time (or linking) stage? Should it be simpler then my option?
Anyway the resolution what barrier stop walk() for very big folders should be task for real programmers.
And maybe I need create recursion-free walk() method for the first or then second level of big-folder hierarghy, but the use current walk() method?

anda_skoa
24th December 2015, 13:19
I am afraid I can't make heads from what you've written.

For debugging I would make sure that there is no threading involved.
I would personally debug using logging, but setting break points in important locations and checking values should work as well.

Obviously that becomes unnecessary when using QDirIterator, since then the whole algorithm is simple linear iteration.

Cheers,
_

artt
25th December 2015, 00:43
I mean that Qt also has its own algorithms that translate Qt code to native C++, so its function, as well QDirIterator could be based on recursion or even more complex function?? Anyway I will use Qt iterator but the main point is if it would help, if not?
I did not found any logging infos relating to Qtcreator, and it would difficult to do as debugger do not provide any information in this case.
In general, I want to realize this application just to provide as a reference that I have real(gui) c++ app to my resume.
And except semi-workable walk() method - other issues are that ones I need to write all this info to xml file, then render to QTextEdit (I think there could be problem in assigning Qtextstream from xml file to Qt textarea with the button, as in Java, exactly that function was limited by heap memory, but the indexation vector of object was created plainly), so it could be additional point. Then I also need to add Qlabels for the displaying of search file results and other controlling information (As well as QLineEdit for entering the name of file and then passing to searchfilename() method).
Could any difficulties appear when launching app.exe directly without QtCreator?

anda_skoa
25th December 2015, 11:59
I mean that Qt also has its own algorithms that translate Qt code to native C++

Qt is a set of C++ libraries, its code is native C++, Qt code is compiled by the same C++ compiler as any other C++ code, there is no "translation" necessary.



so its function, as well QDirIterator could be based on recursion or even more complex function??

Yes, it could be based on explicit recursion or using a stack, etc.
The code is available so no need for speculation if this is important.



Anyway I will use Qt iterator but the main point is if it would help, if not?

Well, it is a well tested class, it is known to work, it is known to be able to traverse large directory structures.
If I had a non working code and a known to work solution, I would consider that helpful.



I did not found any logging infos relating to Qtcreator, and it would difficult to do as debugger do not provide any information in this case.

Simple logging can always be done with qDebug() or C++ output streams.



In general, I want to realize this application just to provide as a reference that I have real(gui) c++ app to my resume.

In that case you might want it to not only work but also be well written.

Cheers,
_

artt
27th December 2015, 20:58
Really, since the last twenty-hours I returned to the project, and almost done it, except 2 things (Some things are even simplier then in Java, despite other - not).
Qdiriterator at least work with the smallest my disk C: - but in connect() statement it freeze gui() extremely.
So I need put in thread where it works plainly, but when I put the options of Qfiledialog to basic walk() method and launched in walkwiththread() I got the run-time error where I am informed that I need probably put Qdialog to GUI thread (not separate one) - so the way out probably is the additional button for choosing file for walk() -- except it also need yet 2 file choosing for other Lister::methods so its functions could not appear the composite, just forked in some way as Qfiledialog could not implemented in separate thread.
The same situation with some kind of fatal error when I put non-static method in wrapperthread() method I also can not realize it, as this method is related in (..Lister f. wrapperthread()), when in non-static method I need to create additional object of Lister class in thread run() method. The only wayout could be making the relating button also static, as I transferred all of "Qwidgets" (buttons,labels,textedit) to Lister.h, defining it in Constructor in Lister.cpp, so all of them are non-static.

anda_skoa
27th December 2015, 21:14
Indeed, having methods static is really weird, very uncommon even in Java.

Glad to hear that you got it working now!

Cheers,
_

artt
27th December 2015, 21:56
So how to resolve that fuct that SLOT-method should be related to its object in connect statement, as well I need the object in run() method to call this method in separate thread?? Now I have the yellow background(and do not know why?) around the static Qtextedit variable when assignong to it in such kind as Lister::textview->

anda_skoa
27th December 2015, 22:31
Sorry, I can't follow.
What is the problem?

Cheers,
_

artt
27th December 2015, 22:58
I try to define such textedit:
Lister.h:
static QTextEdit* textview;
In Lister.cpp:
//Lister::textview = new QTextEdit(); -- in this case I got yellow background. So error.
If textview=new QTextEdit() - just if non-static.
So I try to make qtextedit non-pointer:
static QTextEdit textview --Lister.h
And define its properties in such kind
Lister::textview.setLineWrapMode(QTextEdit::NoWrap );
But I cannot add textedit to layout as other ones are added as ponters:


layout->addWidget(label3);
layout->addWidget(Lister::textview); -- got not matching functions error
//candidates are: void QBoxLayout::addWidget(QWidget*, int, Qt::Alignment).
I want to use static textedit in static-slot function so it could be applicable in threadwarapper function, as non-static results in error-carsh as I have written early.
Despite the solution could be using non-static function with non-static texedit as well, putting it in static-warpper function of Lister class, then putting it in Thread::run, then calling Thread::start, and putting it in slot of threadwrapper function -- but it should be 4-tier hierarchy, but creation the object at first level could also lead to crash as in case of 3-tier option.
If you dont understand about Qdialog so I can refer to some code:


void Lister::walki() {
QFileDialog* filedlg;
QString path0=filedlg->getOpenFileName();//If I put these 2 lines in this method and then put this method in thread it lead to crash as without it would work fine if put to thread as without thread -- gui freeze..
QDirIterator* it = new QDirIterator(path0, QDirIterator::Subdirectories);

anda_skoa
28th December 2015, 09:27
I try to define such textedit:
Lister.h:
static QTextEdit* textview;
In Lister.cpp:
//Lister::textview = new QTextEdit(); -- in this case I got yellow background. So error.

What is the actual error message?


So I try to make qtextedit non-pointer:
static QTextEdit textview --Lister.h
And define its properties in such kind
Lister::textview.setLineWrapMode(QTextEdit::NoWrap );
But I cannot add textedit to layout as other ones are added as ponters:


layout->addWidget(label3);
layout->addWidget(Lister::textview); -- got not matching functions error
//candidates are: void QBoxLayout::addWidget(QWidget*, int, Qt::Alignment).

You forgot the & to get the object's address.



I want to use static textedit in static-slot function so it could be applicable in threadwarapper function

Since Lister is the class that you run in a thread, it would be better if it did not have some UI members.
And using static methods as slots is very uncommon, better do it properly.


If you dont understand about Qdialog so I can refer to some code:


void Lister::walki() {
QFileDialog* filedlg;
QString path0=filedlg->getOpenFileName();//If I put these 2 lines in this method and then put this method in thread it lead to crash as without it would work fine if put to thread as without thread -- gui freeze..
QDirIterator* it = new QDirIterator(path0, QDirIterator::Subdirectories);

Since UI can be used from secondary threads the obvious way is to use the dialog in the slot that is connected to the button, get the file name, then start the thread with the obtained data.

Oh, and you probably want to use getExistingDirectory().

Cheers,
_

artt
28th December 2015, 21:05
What is the actual error message? -- Something like "undefined reference"
"You forgot the & to get the object's address" - I tried to do
layout->addWidget(&Lister::textview), layout->addWidget(Lister::(&textview)) - but it is incorrect.
"Since Lister is the class that you run in a thread, it would be better if it did not have some UI members" - how can I assign qtextedit or extract the qlinedit, and then put in SLOT() connect - it was early in main() but it is rather impossible to organize in such way.
"And using static methods as slots is very uncommon, better do it properly" - but it exactly works well, maybe as non-static, but in threadwrapper exactly non-static lead to crash. So I assumed as indexate and writexmlfile is static maybe just them put in thread but renderdirectly and renderfromxml (with non-static) put in GUI thread as it it crash in thread for now, as well as the search function. So what is "properly" for you?
I think that of course the dialogchoosers could be put in Main gui or in separate thread.

anda_skoa
29th December 2015, 09:46
What is the actual error message? -- Something like "undefined reference"

Maybe you forgot to define the variable and only have it declared?

In general not providing the forum with the actual error message makes it impossible to determine what could be wrong and suggest fixes.



"Since Lister is the class that you run in a thread, it would be better if it did not have some UI members" - how can I assign qtextedit or extract the qlinedit, and then put in SLOT() connect - it was early in main() but it is rather impossible to organize in such way.

Since you give no indication what you are actually trying to do we can only guess.
Just make the connection from the place were you have both the lister object and the text edit.



"And using static methods as slots is very uncommon, better do it properly" - but it exactly works well, maybe as non-static, but in threadwrapper exactly non-static lead to crash. So I assumed as indexate and writexmlfile is static maybe just them put in thread but renderdirectly and renderfromxml (with non-static) put in GUI thread as it it crash in thread for now, as well as the search function. So what is "properly" for you?

You can use static functions if you don't need them to access any data from the instance of the object.
When you start to need static members then it is usually a good hint that these are not static methods at all.

It is hard to keep track of what you do with which class, but it seems you are trying to do too much in one class.
Lets assume Lister is the class that you work with on the higher level.
It will have a slot to ask for the base directory and then create an instance of your walker thread.
That thread class then has the method to traverse the directory tree and keeps the results in a member.
The lister can then retrieve the result once the thread is done.

If you need to report results as they come in, then let the thread emit them via signal instead and receive them in a slot of the Lister.

No need for any static methods or static members, all operations in Lister happen in the main thread, can use UI there as well.

Cheers,
_

artt
30th December 2015, 07:48
I defined textview (qtextedit) variable in Lister.cpp (in constructor) and declared in Lister.h. I got undefined reference when I put it Lister::textview, and make it static before. When not static, and textview* pointer it did not induce such error. So may be issue is in getting the adress/pointer of static variable? When not static I could not use it in static slot -- you should understand That I need to make Lister object in run() of thread then I could not refer to such object in connect() statement as there is another general Lister object so it is the reason to use static method in threadwrapper SLOTS...

Added after 8 minutes:

walk() as traverse method do not induce error so I can use it as static and in separate thread. The results of walking is stored in static qlist listed variable and it works enough fine as I can pass such list of properties as for the xmlcreation file as well for direct rendering of gotten xml to textview. But as I have said I could put file chooses dialog in walk() and then in thread as I got the error that dialog should be in main gui thread. So I need put it there or in separate thread as well as with separate button for file chooser.

anda_skoa
30th December 2015, 09:45
I defined textview (qtextedit) variable in Lister.cpp (in constructor) and declared in Lister.h.

You cannot define a static variable inside a constructor.
A static variable is always defined with its type and fully qualified classname and, optionally, a default value.



I got undefined reference when I put it Lister::textview, and make it static before.

Sounds like you have not variable definition.



When not static I could not use it in static slot -- you should understand That I need to make Lister object in run() of thread then I could not refer to such object in connect() statement as there is another general Lister object so it is the reason to use static method in threadwrapper SLOTS...

Right, but if you consider the responsibilities, then you see that the thread does not need to call anything in Lister if Lister is the class that controls the overall process.

Lister would simply get the user input, create a thread with that input and then run the thread.
The thread class would travese the directory tree and either send results as it goes or just store it until it is done.
Lister would then either listen to the updates or retrieve the final result.



walk() as traverse method do not induce error so I can use it as static and in separate thread.

Since it is not used anywhere else, you can just put it into the thread.



The results of walking is stored in static qlist listed variable

If you put the method into the class that needs it, you can simply store the data in a non-static member.

Cheers,
_

artt
30th December 2015, 12:21
"You cannot define a static variable inside a constructor.
A static variable is always defined with its type and fully qualified classname and, optionally, a default value."
--Yes I will see it later in my Qt creator, as the static Qlist <Filewalker> listed definition was the first issue on this Qt project
--How it was simplier in java - I have just one class Filewalker, and it worked.

anda_skoa
30th December 2015, 12:48
The same symbol rules apply in C++ as well, a class name can only be used once.

You need a different package (Java) or namespace (C++) to use a class name again.

Cheers,
_

artt
31st December 2015, 14:59
I do not understand what you mean under using class name again (need new namespace). But I defined static variable (widget) - but due to it I got such error (as it is static widget definition) --
"QWidget: Must construct a QApplication before a QPaintDevice" -
as I have read about it on this forum it is because the static variable (textview) appear before the application so as I
understand before Lister (f) object with other widgets, and due to global feature of static widget it appears that it is "physically" disconnected with other widgets (that is indside window-qwidget). So probably it is unreal to use static widget in such case, and the advice to delete inheritance on Qwidget is unreal also. So just to make it non-static probably...
Despite this issue is not the main just using non-static SLOT-function in threadwarapper SLOT, that needs the static slot inside run(), that in turn nessesiate the static variable(widget).
So is it possibel to use static widget?
Or not create Lister object inside run(), but call its non-static SLot-function?

anda_skoa
31st December 2015, 15:09
I do not understand what you mean under using class name again (need new namespace).

You wrote that in Java there would only be one FileWalker class. That is the same in C++, class names need to be unique.



But I defined static variable (widget) - but due to it I got such error (as it is static widget definition) --
"QWidget: Must construct a QApplication before a QPaintDevice" -

Good point, another very good reason not to do static objects.


Despite this issue is not the main just using non-static SLOT-function in threadwarapper SLOT, that needs the static slot inside run(), that in turn nessesiate the static variable(widget).

There is no reason whatsoever to call a static method from inside run(),



Or not create Lister object inside run(), but call its non-static SLot-function?
I have lost track of what Lister is, but you seem to try to shoe-horn to things into one class.

You need
- a class that the application works with, that provides a slot that asks for user input, creates a thread, runs the thread and collects the result
- a thread that runs the directory traversal

If you want you can of course split the thread in two classes, the thread itself and a class that implements the directory traversal.

There is no static required in any of this.

Cheers,
_

artt
1st January 2016, 14:05
ASSERT failure in QWidget: "Widgets must be created in the GUI thread." - here I got such error when placing non-static method in threadwrapper SLOT - it seems the same as with Qdialog (that I can find solution or absolve using of it) - it is due exactly to non-static method that uses non-static Qtextedit textview. That is why if it is also insolubilitable issue - I can set back using such non-static method is threads -that probably is affordable here. I use "textview" in readfromxmlfile and renderingdirectly xml to Qxtextedit, so it should not be very time consuming work (in Qt it seems to be faster then in Java, despite I did not tried it for the whole disk), and clearing textedit - so I could leave it in Gui-thread, as well the filenamesearch method that exploit another Qwidget(Qlabel) for the rendering finded result so I laso could not allow to use it as static.
Anyway I will refer here for the whole code so the solution could be proposed - f.e. with signals, despite the signals are buttons in my case.

anda_skoa
1st January 2016, 14:23
ASSERT failure in QWidget: "Widgets must be created in the GUI thread." - here I got such error when placing non-static method in threadwrapper SLOT - it seems the same as with Qdialog (that I can find solution or absolve using of it) - it is due exactly to non-static method that uses non-static Qtextedit textview.

As the error clearly indicates you are trying to create a widget from a thread that is not the main thread.
Whether that code is in a static or non-static method does not matter a bit.
This has obviously nothing to do with static vs non-static.

Cheers,
_

artt
1st January 2016, 14:36
No, this error appears exactly here where I use non-static method in qthread::run(), as the static methods such as walk() and writexmlfile() that do not use Qwidgets works as in thread as without it - but walk() in GUI-thread freeze extremely, so thread is nessesary there anyway. If turn back to my first topic on forum about Swingworker analogue in Qt, that in Java swingworker is used for background processes such as traversing, but probably the assigning the text (despite very large) to Qtextedit is not so one, so the issue could be solved in manner not using threads for rendeing..
here is whole code:http://s000.tinyupload.com/?file_id=05341985004786237054

anda_skoa
1st January 2016, 15:37
No, this error appears exactly here where I use non-static method in qthread::run()

No sorry.
It happens because it is called from QThread::run(), not because the method is non-static.



that in Java swingworker is used for background processes such as traversing

And the same would work in C++ as well.



but probably the assigning the text (despite very large) to Qtextedit is not so one

This has been explained before: UI can only be interacted with from the main thread.
You worker thread either emits data as it goes and the a in the main thread handles it, or it just runs and you handle the result once it has completed its task.

- Lister is your main class, it handles the user interaction
- don't create instances of Lister in threads
* it is a widget
* it deals with the user interaction
* you already have an instance of Lister
- don't call any methods of Lister in the threads
- put code that you want the threads to execute into the thread classes

Cheers,
_

artt
1st January 2016, 16:06
1. It happens because it is called from QThread::run(), not because the method is non-static
2. - don't create instances of Lister in threads
These are two fine remarks. but - how would you call (1) non-static method in run, without (2) creating
Lister object - the [static] Lister::walk() works from within run(), because I do not use non-statci method, I do not create Lister there, so I do not create no Qwidget out of GUI-widget.
3. Indeed I can left as it is - with 2 first methods in threads and others - out of there.
4. About nessecity to create qwidgets just in Main-gui (despite I do not read about it exactly in official Qt documentation) I did understand, as It seems to be 2 different widgets, so not composite one, despite Java suppoer so. As it is impossible in Qt it is very big deficiency, as I also could not assign value to Qlabel, or take the text from Qlinedit - in separate thread.

anda_skoa
1st January 2016, 16:34
but - how would you call (1) non-static method in run, without (2) creating
Lister object - the [static] Lister::walk() works from within run(), because I do not use non-statci method, I do not create Lister there, so I do not create no Qwidget out of GUI-widget.

See the last two points.



I also could not assign value to Qlabel, or take the text from Qlinedit - in separate thread.
Trivial to do with a signal from the thread connected to a slot in the label, line edit or any other class on the main thread.

Cheers,
_

artt
1st January 2016, 16:41
"Trivial to do with a signal from the thread connected to a slot in the label" -- it is not so trivial for me.
I have looked for signals yesterday, and saw such sample
...Thread.h
signals: void signalmethod();
public: run();
then in thread.cpp
Thread::run() {
signalmethod();
} but I did it with static method. But here is non-static one?? what kind (how it should look like) of signal I shpuld use?
2. what 2 last point?

anda_skoa
1st January 2016, 17:30
I have looked for signals yesterday, and saw such sample

Right, just declare a signal and emit it in run.
The code creating the thread object can then connec this signal to its own slot or to the slot of another class.

E.g. if you had a signal like this



signals:
void updateText(const QString &text);

one could directly connect it to a label that should show that text


connect(thread, SIGNAL(updateText(QString)), label, SLOT(setText(QString)));




2. what 2 last point?



- don't call any methods of Lister in the threads
- put code that you want the threads to execute into the thread classes

artt
1st January 2016, 17:43
connect(thread, SIGNAL (update(QString)...) -- then I need to make the Qtextedit (Qlabel) field the member of Thread class -but other Qbuttons will be the Lister members - as well as the layout widget...
But it need to be composite (sorry - it should call - solid or indivisable to be more apt), how one widgets would be in one gui, the others - in another??

anda_skoa
1st January 2016, 18:55
connect(thread, SIGNAL (update(QString)...) -- then I need to make the Qtextedit (Qlabel) field the member of Thread class

Nope.

Cheers,
_

artt
1st January 2016, 19:25
So how? In updatetext() I need to use Qtextedit field, and how I use this field without Lister object creation, or I shoud create Qtextedit in Thread object - but it shoud be in GUI-thread (to avoid ASSERT failure).
I did not used sognal emitting never.

anda_skoa
1st January 2016, 19:31
The thread emits the signal, the widget receives it.
You connect in Lister, when you've created the thread instance, before starting it.

So the widget can either be Lister itself or one of its members.
No need to have a member in the thread.

Emitting the signal is just


emit updateText(someQStringVariable);


Cheers,
_

artt
1st January 2016, 19:52
How can I use QTextEdit textview in signal without creating Lister object, as it is the part of Lister class?

anda_skoa
1st January 2016, 21:43
You either connect to a slot of the text edit itself or to a slot in Lister and the call setter methods on the text edit from that slot.

Cheers,
_

artt
1st January 2016, 23:19
I cannot suggest how? Would you? Either way I need Lister->textview or the most simple Lister::textedit..

anda_skoa
2nd January 2016, 10:02
I cannot suggest how? Would you? Either way I need Lister->textview or the most simple Lister::textedit..
Lets assume the slot is a method of Lister.
Then you can just address any member with its name.
Just as you would in Java.

Cheers,
_

artt
2nd January 2016, 11:09
What kind of signal should be- declaration and definition; Anyway it should be connected with the button - renderdirectly (or from file) - so I need anyway the object of Lister.
So if I add signal I need Lister object - so task appear more complex - and Slot is also Lister function and need its object if non-static.

anda_skoa
2nd January 2016, 12:09
What kind of signal should be- declaration and definition

Comment #100 has an example for a declaration.
The definition of a signal is handled by MOC, nothing to do for you.



Anyway it should be connected with the button

QPushButton has a setText slot, so that would work just like for a label.



So if I add signal I need Lister object

Not sure what you mean.
You don't need a Lister object to add a signal to the thread class.

You don't need a Lister object to connect if there is some place other than Lister that knows both the thread object and the receiver object.
But Lister should have both, so it is the best place to put the connect into.
And you already have an instance of Lister, so no new thing required.


and Slot is also Lister function
Not necessarily as you can connect to any other object that has a slot matching the signal.

However, since your target for the signal seems to change a lot (first you had a label, then a text edit, now you've asked about a button), it might be easier to just connect to a slot in Lister and handle whatever UI update from there.

Cheers,
_

artt
2nd January 2016, 13:20
setText() is about adding the label for button itself- anyway it would not affect probably the Qtextedit area as it is the another widget. Anyway I need to use non-static variable of some class (in that case the Lister, or any other) that should be instatiated. If instantiated in some thread -- it will be out of non-GUI thread that lead to error.
What signal could do - just trigger slot reaction- or how it put textstream to created Lister textview if it needs to put inside another thread first. Could your provide workable example of it, I think it should not be difficult?

anda_skoa
2nd January 2016, 15:03
setText() is about adding the label for button itself

Yes, correct.



Anyway I need to use non-static variable of some class (in that case the Lister, or any other) that should be instatiated.

Correct and you already have an instance of Lister.



If instantiated in some thread -- it will be out of non-GUI thread that lead to error.

Exactly, so don't do that.



What signal could do - just trigger slot reaction- or how it put textstream to created Lister textview if it needs to put inside another thread first.

I am afraid I have no idea what you mean.
What do you "need to put inside another thread first"?



Could your provide workable example of it, I think it should not be difficult?

A workable example for what?

Cheers,
_

artt
2nd January 2016, 15:31
I need the "textview" and qlabel to assigned inside thread, in another case, I should leave as it is. Whether you propose to create separate
thread for rendering text, but Qtextedit assigned to be done outside of it. What then the sense of it? What work of such thread would do? How it would relinquish the main-gui as the asisgning should be done just there. Maybe such assigning could not lead to freezing so any sense to make new thread, despite in Java rendering of big xml files was time consuming enough?
Then why I need to use textupdate of qpushbutton?

anda_skoa
2nd January 2016, 16:56
I need the "textview" and qlabel to assigned inside thread

No. Remember only the main thread interacts with widgets directly.

You need the thread to send data via signal and the slot puts that data onto widgets.
The given example was for text, i.e. QString.

Cheers,
_

artt
2nd January 2016, 21:54
Lets assume that several signals could be connected to one slot -- despite it seems that it could be without signals in the whole.
We have such method:

void Lister::readxmldirectly() {
QByteArray* ba=new QByteArray();
QXmlStreamWriter stream(ba);
stream.setAutoFormatting(true);
stream.writeStartDocument();
stream.writeStartElement("FILESYSTEM");
foreach (Filewalker* fp, Lister::listed) {
stream.writeStartElement("FILE");
stream.writeStartElement("NAME");
..........
QTextStream ReadFile(ba); (1)

Lister::textview->setText(ReadFile.readAll()); (2)
}

then I could put the (1) in signal processing method --signal()
then emit it, or simply put in run(), but in this case the signal() should be static one.
Then pass the (1) Qtextstream already outside of thread in SLOT of Lister
where would be the last line of above method-

Lister::textview->setText(ReadFile.readAll());
--If use the emit signal() --where put [emit signal()]?
Inside run()?
And it is in case if the signature of connect would be such one,

connect(f->readxml, SIGNAL(clicked()),f, SLOT(readthread()));
As I need connect readxml button with Slot
--So I need put

Lister::textview->setText(ReadFile.readAll()) just inside (readthread())??

anda_skoa
3rd January 2016, 10:26
Lets assume that several signals could be connected to one slot

Yes, that is possible.



despite it seems that it could be without signals in the whole.

Sure, signals are only one option of transferring data from a worker thread to the main thread.
Usually the most convenient way though.



We have such method:

void Lister::readxmldirectly() {
QByteArray* ba=new QByteArray();
QXmlStreamWriter stream(ba);
stream.setAutoFormatting(true);
stream.writeStartDocument();
stream.writeStartElement("FILESYSTEM");
foreach (Filewalker* fp, Lister::listed) {
stream.writeStartElement("FILE");
stream.writeStartElement("NAME");
..........
QTextStream ReadFile(ba); (1)

Lister::textview->setText(ReadFile.readAll()); (2)
}

Assuming that the last two statements are not in the loop, why not just simply let the QXmlStreamWriter work on a QString and set that on "textview"?

Cheers,
_

artt
3rd January 2016, 14:11
Not the first statement is the whole method. The second statement is just last line. That I wanted to put just last line out of workerthread, so assignt textstream to qtextedit in GUI-thread or convert it beforehand to Qstring and then to assign just it to qtextedit. But I cannot know if I can to return method of such big qstring in about 1.5 million lines passing it to textview.setText(...)?

anda_skoa
3rd January 2016, 14:17
Not the first statement is the whole method. The second statement is just last line.

Ah, ok.



That I wanted to put just last line out of workerthread, so assignt textstream to qtextedit in GUI-thread or convert it beforehand to Qstring and then to assign just it to qtextedit.

Right, that would be my approach as well:
- connect thread's signal to textview's setText()
- create the QString in the worker thread
- emit string via signal



But I cannot know if I can to return method of such big qstring in about 1.5 million lines passing it to textview.setText(...)?
No better way than to try and find out :)

Cheers,
_

artt
3rd January 2016, 15:40
So how I need to emit signal with run() method? Rthread::run{ Lister::renderxmlsignal(); emit renderxmlsignal();}. But how to connect 2 signals with 1 slot. With 2 connect statement, but with the same slot? The signall emitting free way could be process listed to xml and save it in operative memory in another big lister Qstring variable like listed2, and just put it textview. Anyway in such method implemetation I need 2 connect statements. Unfortunately thread.start() can just return void type, no qstring, so I need to save big qstring somewhere or use signal emitting.

anda_skoa
3rd January 2016, 16:45
So how I need to emit signal with run() method?

See comment #104


But how to connect 2 signals with 1 slot. With 2 connect statement, but with the same slot?

Yes.



Unfortunately thread.start() can just return void type, no qstring, so I need to save big qstring somewhere or use signal emitting.
QThread::run() is executed in another thread, so even if it would return something your main thread would not have access to it.

So indeed, you can either store the string and retrieve it after the thread is finished or emit it via a signal.

Cheers,
_

artt
4th January 2016, 18:21
I do not understand how link this 2 connect statements:
f.i. connect(thread, SIGNAL(updateText(QString)), label, SLOT(setText(QString)));
what should be (updateText(QString)) - should it be wrapper of run() or start(), why to use Qstring argument?
I do not clearly grasp the linking of signal-slot (if button-click() --> trigger the SLOT), but here I want to signal() return the whole Qstring, then SLOT take it and assign to textview. Or you mean (updateText(QString)) is just for emit signal() so it takes the Qstring?
Why I cannot just use (thread, SIGNAL(start(), textview, SLOT(setText()) and or Qstring argument is exact argument that link signal and slot?
Anyway I need use button after clicking which I settext() but I cannot use it in aforementioned example.
So if just use it -- the textview would be filled just after launching the application, but I need use it just after clicking.
So as I understand I need some intermediate variable as listed2 where I can put the results of xml processing, and then put it in Qtextedit yet in main-gui...

anda_skoa
4th January 2016, 18:50
I do not understand how link this 2 connect statements:
f.i. connect(thread, SIGNAL(updateText(QString)), label, SLOT(setText(QString)));

This is only one connect statement.



what should be (updateText(QString)) - should it be wrapper of run() or start()

It is a signal, it doesn't wrap anything.



why to use Qstring argument?

You want to send text from the thread to the GUI, QString is Qt's class for text.



Or you mean (updateText(QString)) is just for emit signal() so it takes the Qstring?

Yes, signals are emitted.



Why I cannot just use (thread, SIGNAL(start(), textview, SLOT(setText())

Who would have thought?
Could it be that thread does not have a start() signal?
Could it be that textview does not have a setText() slot?



Anyway I need use button after clicking which I settext() but I cannot use it in aforementioned example.

If you need to set a text when a button is clicked, create a slot that you can connect to the button's signal and call widget setters from there.



So as I understand I need some intermediate variable as listed2 where I can put the results of xml processing, and then put it in Qtextedit yet in main-gui...

I have no idea what you mean.

Cheers,
_

artt
4th January 2016, 19:13
Our last spin of discussion is probably the most worthless and long -- of course I need simple action triggeed by button.
As all of the others. So I see just transient variable, that got qtext variable after thread processing, and then assigning it to Qtextview in connect() statement by button. Notheing more... Despite processing xml, then assigning to variable, despite using some aditional resources as virtual memory would be justified, as I just put this variable to Qtextview in readxml() and maybe free the virtual memory in the same method.
So my SLOT(readxmlinthread()) would like as:
readxmlinthread() {
thread.start();//process to xml Qstring listed2
textview.setText(Lister::listed2);
//use destructor to free listed2 on heap;
}

artt
4th January 2016, 21:35
Here I defined such variable and slot method in Lister.cpp:

QList <Filewalker*> Lister::listed;
QString Lister::listed2("dddddd"); //I assigned such simple text for simple testing
...
void Lister::readthread() { //As slot function
RThread* R=new RThread();
R->start();
textview->setText(Lister::listed2); //It doesnt render dddddd
textview->setText("Lister::listed2"); //But it render "Lister::listed2" --So did I incorrectly assign listed2 to textview with setText()?
}

anda_skoa
4th January 2016, 22:17
So I see just transient variable, that got qtext variable after thread processing, and then assigning it to Qtextview in connect() statement by button

A connect doesn't assign anything.
It provides a connection between a signal and a slot.
When the signal is emitted, the slot is invoked.
If the signal carries arguments, then the slot is called with these arguments.



So my SLOT(readxmlinthread()) would like as:
readxmlinthread() {
thread.start();//process to xml Qstring listed2
textview.setText(Lister::listed2);
//use destructor to free listed2 on heap;
}
That is obviously not going to work, as the thread is running in parallel so that variable might or might not have been set at the point of reading it.
Also obviously not thread-safe.

Hence the suggetion to use a signal:
- is thread-safe
- sets the widget's value then the value has been calculated
- avoids hacks such as this static variable

Cheers,
_

artt
4th January 2016, 23:45
I see that it doesnt work - but I ask probably 7-8 time here - how connect Button, signal from thread with xmlprocessing results and textview it main gui? i have no suggestion as there is nessecity of transient variable.

anda_skoa
5th January 2016, 12:17
I see that it doesnt work - but I ask probably 7-8 time here - how connect Button, signal from thread with xmlprocessing results and textview it main gui?

So what is the problem with the examples that were already given?

Comment #7 shows how to connect a button to a slot from within the receiver class.
Comment #13 shows a connect of a button signal to a slot from outside both sender and receiver.
Comment #44 has several examples of connecting signals that carry arguments.
Comment #100 shows a declaration of a custom signal and how to use it as a cross-thread data exchange mechanism.
Comment #104 shows how to emit such a signal.

Cheers,
_

artt
6th January 2016, 00:02
I have looked through your references: but if signal() is just declared, not defined what is the sense of its argument.
If I declare:
signals: setuptext(Qstring);
and then emit...
How I can link void readxmldirectly() [that shapes these mega QString as the result of xml processing] to this signal?
How I can link as well button with clicked() signal??
Maybe it is impossible to realize such option -- maybe it needs some queue or some nested signal-slot connection?
As you cannot provide some blueprint, I think you have no idea too, or I am not correct -- as the task not simply connect the signal with slot, but connect signal from button with the output of thread processing to slot??
Maybe I could override in such way -- button,clicked(Qstring) and clicked is triggered when I emit signal with the thread::run() output?

anda_skoa
6th January 2016, 00:38
The button's clicked() signal gets connected to a slot.
The slot creates the thread instance, connects the thread's signal and starts the thread.
The thread emits the signal when it is done.

Cheers,
_

artt
6th January 2016, 01:15
void Lister::readthread() {
//RThread* R=new RThread();
//R->start();
textview->setText(Lister::path0);
textview->setText("Lister::listed2");
} -- And returning to my last SLOT -- it also do not work with path0, so the issue is not in thread Rthread as the path0i defined... Maybe I need use there signal finished() of Qthread as it would be like join() in Java, then I can assign listed2 variable, but textview->setText(Lister::path0) with predefined do not work.
So I need connect(button,clicked(), f, readthreadxml());
Inside readthreadxml() i need use another slot()? Or how -- but it should emit some signal
connecting with some event --should it be the craetion of Lister f object or start of application?
...The thread emits the signal when it is done -- shoukld this signal to be void without nothing or it should be the readxnldirectly() content?

anda_skoa
6th January 2016, 08:28
So I need connect(button,clicked(), f, readthreadxml());

Yes



Inside readthreadxml() i need use another slot()?

Inside that method you have another connect().
Whether you connect to a slot in Lister or directly to the textview is up to you.



Or how -- but it should emit some signal

No, the thread emits the signal when it has finished creating the content you want to show



...The thread emits the signal when it is done -- shoukld this signal to be void without nothing or it should be the readxnldirectly() content?
Well, it is easier if the signal transports the content because then you can directly connect to textview.

Cheers,
_

artt
6th January 2016, 09:07
"Inside that method you have another connect() -- I do understand as slot without connect() nothing means.
Whether you connect to a slot in Lister or directly to the textview is up to you."
--Indeed I need to define the slot of nested connect() in Lister.cpp, so I need to create Lister object again(or beforehand to be strict), and it will be out of created in main() so it would be the error as ever, or I need static slot with static textview -that is impossible.
Ot I should simply use textview->setText(...), no Lister->textview->setText(...).
Anyway --there is build in finished() signal in qthread as I wrote early, maybe it would be option.
And I do not understand why
void Lister::readthread() {
textview->setText(Lister:path0);
textview->setText("Lister::listed2");
} do not render path0 that is not empty and predefined in code. If it would work maybe I would check my previous option

anda_skoa
6th January 2016, 16:23
--Indeed I need to define the slot of nested connect() in Lister.cpp, so I need to create Lister object again

Why would you need another instance of Lister?



Anyway --there is build in finished() signal in qthread as I wrote early, maybe it would be option.

Of course.
You could also store the result in a member of the thread and retrieve it from the slot connected to finished().



And I do not understand why
void Lister::readthread() {
textview->setText(Lister:path0);
textview->setText("Lister::listed2");
} do not render path0 that is not empty and predefined in code. If it would work maybe I would check my previous option
That should always display "Lister::listed2", as this is the value that is set on the textview.

Cheers,
_

artt
6th January 2016, 19:22
void Lister::readthread() {
textview->setText("Lister::listed2");
textview->setText(Lister:path0); //In this case 2nd line render but no first one, so the first line do not //render anyway
}

I have found the solution but not very fine as it works but for big folders like C:\Windows it use too much memory for the whole Windows XP system.


void Lister::slot() {
textview->setText("Lister::listed2");
textview->setText(Lister::listed2);
}

void Lister::readthread() {
RThread* R=new RThread();
R->start();
QObject::connect(R, SIGNAL(finished()),this, SLOT(slot()));
//textview->setText("Lister::listed2");
//textview->setText(Lister::listed2);
} -- So I can do the conclusion about inefficiency of using threads for rendering a big text areas to Qtextedit.

anda_skoa
6th January 2016, 19:58
You probably want to connect before you start the thread.
Otherwise the thread could be finished before you establish the connection.

Cheers,
_

artt
6th January 2016, 20:33
No it render small folder xml immediately, but for big folder I need wait about minute to see the xml in textview, despite hunging began before it, and after rendering continues and deteriorate.
QObject::connect(R->start(), SIGNAL(finished()),this, SLOT(slot())); using R->start() instead R lead to compile error.

anda_skoa
7th January 2016, 01:32
QObject::connect(R->start(), SIGNAL(finished()),this, SLOT(slot())); using R->start() instead R lead to compile error.
Why would you even try that?

It has nothing to do with what I wrote.
I pointed you to a potential race condition and suggested a fix for it.

Cheers,
_

artt
7th January 2016, 21:29
Why do you state that I connect before the start of thread as it is obvious from that excerpt of code that R->start(); then connect(R,finished...). And it works in general but with memory leak or so. Anyway what would you suggest just with your version of emitting signal despite here is built-in finished() signal. And it seems is the simpliest way

anda_skoa
8th January 2016, 12:52
Why do you state that I connect before the start of thread

No, I said you should connect before starting.



as it is obvious from that excerpt of code that R->start(); then connect(R,finished...)

Exactly.
Start before connect, i.e. the wrong way around.

Cheers,
_

artt
9th January 2016, 00:36
"terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
terminate called recursively..."
if I put connect before start of thread (I need click button twice so it incorrect in principle as it was without nested concnet())
Anyway as in other way. there is bad_alloc, despite I put Lister::listed2 on heap memory: bad_alloc is when I put in the end
delete Lister::listed2; I need probably uqual it to Null. But in my first variant-- evrything works fine despite temporal freezing.
But after 2-3 minutes the whole buncg of xml from WINDOWS folder is shown in textview.

anda_skoa
9th January 2016, 13:12
if I put connect before start of thread (I need click button twice so it incorrect in principle as it was without nested concnet())

You need to connect before start or risk missing the signal.
Usually we want our programs to work reliably, but if you can live with your program sometimes not working then keep it the way you are connecting now.



Anyway as in other way. there is bad_alloc, despite I put Lister::listed2 on heap memory: bad_alloc is when I put in the end
delete Lister::listed2; I need probably uqual it to Null.

Whatever listed2 is, it is likely already using heap allocation internally, so that wouldn't change anything anyway,

Maybe you are running out of memory.

Cheers,
_

artt
10th January 2016, 02:18
"You need to connect before start or risk missing the signal" -- my signal is after finishing the thread, so it is enough time to go for second statement after starting the thread.

anda_skoa
10th January 2016, 10:05
"You need to connect before start or risk missing the signal" -- my signal is after finishing the thread, so it is enough time to go for second statement after starting the thread.

The signal is emitted by the second thread. If you want to be sure to catch it, you have to connect before you start that thread.

Cheers,
_

artt
16th January 2016, 17:44
I do think that it works correctly as it works, except memory issues due to a lot of using of dynamic allocation. But just in last case I cannot settle it? So it is funny that there is no memory leak in another cases when I use new operator and pointers as I almost do not use delete operator as even going out of scope do not release memory as in case of stack allocation.
In general I understand that the using of pointers especially in objects cases is for using heap memory (despite error-prone), that allow far more rich memory resourses then stack case.
If we use pointers that are the same in case of 32-bit Windows Xp -- 4 bytes (as it improbably is relevant to the real object size). Why to use the pointer if it is just the reference, name (e-adress) of object but its real one take the whole memory size? So the real difference is in the type and possibilities of volume of memory allocation? The pointer itself do not free the system to put the whole object with it nessesary memory size.

anda_skoa
16th January 2016, 17:59
I have no idea what you mean.

If you have an object allocated in the stack, its destructor will run and its memory will be released.
An object can internally use heap allocation, so very often is it unnecessary to do it manually, e.g. when using a container such as a list or vector.

Manually allocated memory needs to be released, either manually or by letting the pointer be handled by a smart pointer or by other management mechanisms, e.g. QObjects' parent/child tree.

And good that you have changed the code to connect the thread's signal before starting the thread.

Cheers,
_

artt
16th January 2016, 22:57
"An object can internally use heap allocation" -- it is fine that you noted (the second time in that thread) it as I did not know before and do not saw it anyway. Do all containers are capable of it?
Do smart pointers allow automatic release of memory, as I used here the object not primitive types pointers?
"QObjects' parent/child tree" -- should it means some kind of Virtual desctructor, when the destructor of base class release also the memory of sub-class?
"And good that you have changed the code to connect the thread's signal before starting the thread" -- I did not changed as it doesnt work(I need click twice at this case). Anyway I need to finalize it as it is as about 2 weeks I do not work on it.
And I mean if Object pointers has the size of 4 bytes and size of Object is about 12 bytes, so what it cahnges that we use pointer as the 12 bytes takes its location for object anyway (or how?), despite we use 4 bytes for new operator. So I mean the difference is only in type, the accesible volume and speed of memory, the way of release but not in real object size?

anda_skoa
17th January 2016, 09:08
"An object can internally use heap allocation" -- it is fine that you noted (the second time in that thread) it as I did not know before and do not saw it anyway. Do all containers are capable of it?

At least all that can hold a dynamic, unknown amount of items.



Do smart pointers allow automatic release of memory, as I used here the object not primitive types pointers?

scoped/unique pointers and shared pointers do that, yes.



"QObjects' parent/child tree" -- should it means some kind of Virtual desctructor, when the destructor of base class release also the memory of sub-class?

No. Instances of QObject derived classes can form a tree of objects. When a node in that tree is deleted, it also deletes all its children.



"And good that you have changed the code to connect the thread's signal before starting the thread" -- I did not changed as it doesnt work(I need click twice at this case). Anyway I need to finalize it as it is as about 2 weeks I do not work on it.

Ok. Just be aware that you are now relying on certain timing aspects.
Only connect before thread start ensures that you get the finished signal.



And I mean if Object pointers has the size of 4 bytes and size of Object is about 12 bytes, so what it cahnges that we use pointer as the 12 bytes takes its location for object anyway (or how?), despite we use 4 bytes for new operator. So I mean the difference is only in type, the accesible volume and speed of memory, the way of release but not in real object size?

I still don't have a clue what you are trying to ask.

A pointer on a 32-bit machine is 4 bytes long, independent of what it points to.
An object has the size it has, independent on how it is allocated.

Cheers,
_

artt
21st January 2016, 10:04
So, I meant. That using of pointers do not save the memory for us. In any way - the object (created with new or without such operator) take the same memory size and space. // And about the topic. Is it theoretically impossible to use static widgets? For example, I want to display message that directory traversing began in qlabel, and after finishing it - that it was finished. In Java it is so simple - static Jlabel mesage1; in qt it is impossible, should I put just in such way: walk0() {this.textview.setText="The indexing began"; walk(); this.textview.setText="The indexing ended"; } . But in case of thread in could be again complicated with memory leak, when using finished() signal.

anda_skoa
21st January 2016, 18:14
An object always needs the same space, not matter how it is allocated.
However, when you allocated on the heap then you obviously also need space for the pointer on the stack.

Aside from there not being any reason what so ever to have a static widget, or any static member, if can be done just like in Java.
In Java your UI element would be allocated on the heap and you can do exactly the same in C++.

Again, it is not necessary in either Java or C++.
You have an instance of Lister, a normal member will be available to all its methods.

Cheers,
_

artt
16th February 2016, 22:52
As several weeks ago I eventually made exe (despite I have not created the pictogram for it, despite it is possible in qt probably), I would like to know is any commercial value of such program or something like that? It has GUI, rendering field, the buttons for saving and reading of xml files with the basic info about all files, as well as the opportunity to search the file.

artt
10th March 2016, 00:41
As far I understood - such app has no commersial value -- despite about 1-2 weeks is needed to create it (So issue appeared what part of real aaplication this one could be, in %?).
To make clear some questions -- I would like to ask - what is idea of qt libraries? Are they based on just existent c++ libraries, how for example qt hadle the threads, networks, as they are absent in plain c or c++?

anda_skoa
10th March 2016, 13:49
Qt provides functionality that has either not been part of the C++ language or wasn't available in cross platform way.

It also has a nice, consistent and well documented API.

Cheers,
_

artt
22nd April 2016, 09:23
I asked about Qt in the context how qt functions and classes are based? Are they based just on c++ and c available resosurces? For instance -- does qstring is made of just C language char array? How for example qthreads, qsockets are realized -- are they irrespective of c++/c functionality? Are they just virtual/abstract creature of qt environment -- or they are decomposed by c++ compiler anyway to compile and translate them in hardware level?

anda_skoa
22nd April 2016, 11:02
The Qt code is C++, it is compiled by your C++ compiler just like any other C++ code.

For things like sockets, threads, files, the normal low level API of the operating system is used and provided to the developer as a common API across platforms.

You can use the code browser on http://code.woboq.org to easily look into the implementations of these classes.

Cheers,
_