Data does not get reflected in real time in Qt TexttEdit widget - c++

I am trying to scan files and its sub directory , the code from Qt Examples works absolutely fine and displays data with QDebug() .
However when i try to it.next() data to a Qlable or textEdit widget , it doesn't show the data in realtime. The data is reflected after the it.hasNext() gets completed. I want to show real time scanning status in the textedit box - Self is new to Qt.
How to show the status for the file being scanned in real time, in the Qt textEdit widget ?
Code is given below .
void MainWindow::findFilesRecursively(QDir rootDir) {
QDirIterator it(rootDir, QDirIterator::Subdirectories);
while(it.hasNext()) {
qDebug() << it.next();
// ui->textEdit->append(it.next()); <<<<<<---- This is note getting updated realtime,
Data get populated after the scan in complted.
}
}
Error
enter image description here

This may or may not be your problem, but do you understand what your code is trying to do?
Your debug statement calls it->next(). You then in your commented-out code call it->next() a second time. If your directory only contains a single file, you've already dumped it. The debug statement eats it.
What you need instead:
QString fName = it->next();
qDebug() << fName;
ui->textEdit->append(fName);
I'm not absolutely positive this is your problem, because I don't know if you commented out your qDebug when you ran it or how big your directory is. There might be something else going on.

Related

How to run Python script from QT creator and print output to GUI

void MainWindow::on_pushButton_clicked()
{
QProcess p;
// get values from ini file
settings->setValue("EMail", ui->lineEditEMail->text());
settings->setValue("Password", ui->lineEditPassword->text());
settings->setValue("Chronological", ui->checkBox->isChecked());
settings->setValue("Current_info", ui->checkBox_2->isChecked());
settings->endGroup();
settings->sync();
// launch python code for login
QString program( "C:/projects/build-test3-Desktop_Qt_6_4_0_MinGW_64_bit-Debug/venv/Scripts/python.exe");
QStringList args = QStringList() << "index.py";
QProcess::execute( program, args );
}
I have this function that is executed after a button is clicked and I need to print the output of "index.py" in to my app. What widget should I use and how? From what I read QTextBrowser should do the trick but I'm not sure how to use it.
This is how my GUI looks like. I'd like to use to output my results somewhere in button right. I didn't add the widget yet, because I'm not sure QTextBrowser is the one I need
The widget you could use for this purpose is QTextEdit (you can set it to be read-only from the graphical user interface).
But if you want to get the output of the execution, you will need a proper instance of QProcess and call the QProcess::readAllStandardOutput() member function to get the standard output.
You may also be interested by QProcess::readAllStandardError() to get the errors in case of failure.
Edit (simple/basic example):
QProcess p;
p.start("path/to/python.exe", QStringList("script.py"));
p.waitForFinished();
QByteArray p_stdout = p.readAllStandardOutput();
QByteArray p_stderr = p.readAllStandardError();
// Do whatever you want with the results (check if they are not empty, print them, fill your QTextEdit contents, etc...)
Note: If you don't want to be blocking with QProcess::waitForFinished(), you can use a signal/slots connection on QProcess::finished() signal.

QScintilla how to continously get cursor position in textEdit widget?

I'm working on a source code editor in C++, using Qt5 and QScintilla as framework. In this project, I want to continously show the row and column of the text cursor (cursor position), so I need a SIGNAL that emmits whenever the text cursor is moved. According to QScintilla docs, cursorPositionChanged(int line, int index) emmits the wanted signal whenever the cursor is moved, so I guess this must be the method that I need? This is what I did so far:
// notify if cursor position changed
connect(textEdit, SIGNAL(cursorPositionChanged(int line, int index)), this, SLOT(showCurrendCursorPosition()));
my code compiles and the editor window shows up as wanted, but unfortunately, I got the warning:
QObject::connect: No such signal QsciScintilla::cursorPositionChanged(int line, int index)
Can someone please provide me with a QScintilla C++ or Python example showing how to continously get and display the current cursor position?
Complete source code is hosted here:
https://github.com/mbergmann-sh/qAmigaED
Thanks for any hints!
The problem is caused by the old syntax of connection that is verified in runtime, in addition that old syntax has as another problem that have to match the signatures. In your case the solution is to use the new connection syntax that does not have the problems you mention.
connect(textEdit, &QTextEdit::cursorPositionChanged, this, &MainWindow::showCurrendCursorPosition);
For more information you can check:
https://wiki.qt.io/New_Signal_Slot_Syntax
Thanks, eyllanesc, your solution works fine!
I also found a working solution myself, just had to remove the named vars from the connection call:
// notify if cursor position changed
connect(textEdit, SIGNAL(cursorPositionChanged(int, int)), this, SLOT(showCurrendCursorPosition()));
...
//
// show current cursor position and display
// line and row in app's status bar
//
void MainWindow::showCurrendCursorPosition()
{
int line, index;
qDebug() << "Cursor position has changed!";
textEdit->getCursorPosition(&line, &index);
qDebug() << "X: " << line << ", Y: " << index;
}
This topic is SOLVED.

Displaying picture that is not in resources of Qt

I am currently writing an application in Qt, which is basically a warehouse. An application reads CSV, enables user to process it and enables to show picture of each good. I tried displaying picture using QLabel and Pixmap, however nothing happens even though the file is in the same folder and the name provided is exactly as it should be. Is it the resources issue or my code fails somehow? Is there any possibility to display the image without adding it to resources in order to avoid adding many photos manually?
void ImageViewer::viewImage(QString imgName)
{
QString pathWithName = imgName;
pathWithName.append(".jpg");
ui->label->setPixmap( QPixmap(pathWithName) );
ui->label->show();
update();
}
Sorry for any mistakes in post creation or code displaying here- it's my first post.
Edit:
I am adding code from MainWindow (called CsvReader in my project) to how I'm invoking the method viewImage:
void CsvReader::on_imgView_clicked()
{
ImageViewer* img = new ImageViewer(this);
img->setModal(true);
img->exec();
QModelIndex List selInd ui->tableView->selectionModel()->selectedIndexes();
QString id = model->item(selInd.first().row(), 0)->text();
img->viewImage(id);
}
Edit 2:
Solved. Had to change path using QDir:
QDir* directory = new QDir("/home/kokos/Magazyn/photos");
QFileInfo checkFile(*directory, pathWithName);
Thanks in advance,
Kokos
Confirm your file's location and existence first. Add this;
QFileInfo checkFile(pathWithName);
if (checkFile.exists() && checkFile.isFile()) {
// your code
}

Display QProcess output in another window

I'm using the QT Creator on Ubuntu.
I have GUI with a mainwindow and another window called "progress".
Upon clicking a button the QProcess starts and executes an rsync command which copies a folder into a specific directory. I created a textbrowser which reads the output from the rsync command. Also clicking the button causes the "progress" window to pop up.
So far so so good, now my problem.
Instead of showing the rsync output in my mainwindow i want it to be in progress.
I've tried several methods to get the QProcess into the progress via connect but that doesn't seem to work.
mainwindow.cpp
void MainWindow::on_pushButton_clicked()
{
if (ui->checkBox->isChecked()
)
m_time ="-t";
QObject parent;
m_myProcess = new QProcess();
connect(m_myProcess, SIGNAL(readyReadStandardOutput()),this, SLOT(printOutput()));
QString program = "/usr/bin/rsync";
arguments << "-r" << m_time << "-v" <<"--progress" <<"-s"
<< m_dir
<< m_dir2;
m_myProcess->start(program, arguments);
}
progress.cpp
void Progress::printOutput()
{
ui->textBrowser->setPlainText(m_myProcess->readAllStandardOutput());
}
I know it's pretty messy iv'e tried alot of things and haven't cleaned the code yet also I'm pretty new to c++.
My goal was to send the QProcess (m_myProcess) to progress via connect but that didn't seem to work.
Can you send commands like readyReadAllStandardOutput via connect to other windows (I don't know the right term )?
Am I doing a mistake or is there just another way to get the output to my progress window ?
m_myProcess is a member of the class MainWindow and you haven't made it visible to the class Progress. That's why you have the compilation error
m_myProcess was not declared in this scope
What you could do:
Redirect standard error of m_myProcess to standard output, such that you also print what is sent to standard error (unless you want to do something else with it). Using
m_myProcess.setProcessChannelMode(QProcess::MergedChannels);
Make the process object available outside MainWindow
QProcess* MainWindow::getProcess()
{
return m_myProcess;
}
Read the process output line by line in Progress. It needs to be saved in a buffer because readAllStandardOutput() only return the data which has been written since the last read.
... // somewhere
connect(window->getProcess(), SIGNAL(readyReadStandardOutput()), this, SLOT(printOutput())
...
void Progress::printOutput(){
//bigbuffer is member
bigbuffer.append(myProcess->readAllStandardOutput();)
ui->textBrowser->setPlainText(bigbuffer);
}

qt5 designer, using fileopen, displaying file path in lineedit, is there an issue doing it this way?

just started using qt,
looked through docs, google, examples, etc.. trying to find simple examples(working mind you)
that showed how to do (imho) simple things, by themselves.
well i stumbled upon my answer and i was wondering if this approach would cause an issue later as the code becomes more complex.
there are more includes than needed for this example, but this is direct from working code.
mainwindow.h:
i added
private slots:
void vpkButton_clicked();
and after
Ui::MainWindow *ui;
i added
QLineEdit *vpkPathTxt;
in mainwindow.cpp:
after
ui->setupUi(this);
i added
connect( this->ui->vpkButton, SIGNAL( clicked() ), this, SLOT(vpkButton_clicked()) );
to connect my ui button to the proper slot, the issue was getting the string from vpkButton_clicked() to display in the line edit i made in the designer,
what ended up working for me was adding this next:
vpkPathTxt = this->ui->vpkPathTxt;
the function in my main.cpp became very easy:
(QString declarations at top outside voids)
void MainWindow::vpkButton_clicked()
{
vpkName = QFileDialog::getOpenFileName(this,
tr("Open VPK File"), "~/", tr("VPK Files (*_dir.vpk)"));
vpkPathTxt->setText(vpkName);
qDebug() << vpkName;
}
the reason i am ask is because it seems a little too easy to be reliable, and the fact that i havent seen it done like this,
any input welcome
thankyou
One problem with your slot is that you don't consider the case where the user discards the "open file" dialog. In this case, the function QFileDialog::getOpenFileName returns a null QString, so you should only proceed with your logic if the return value was not a null string:
if (!vpkName.isNull()) {
...
}
The second problem is as follows and I made some assumptions since I don't see your full code:
I guess you want to load a file using the file name the user has chosen in the dialog. But you set the file name in the line edit too, which the user can edit by hand. I also guess that the actual file loading happens in a different step (i.e. after clicking another button), so after the user has edited the file name by hand in the line edit it won't be the same than in your local variable vpkName.
When loading the file I'd read the contents of the line edit instead of the variable vpkName so the edit made by hand will be respected.
A different method is to also watch for editing of the line edit and reflect the changes in your variable too. Then it will be ok to read the variable instead of the line edit when loading the file later on.