Unsolved Problem with QLineEdit settext()
-
I have a problem with getting settext to work in a particular instance for a Qlineedit.
I created this using Qt Creator 4.2.1, Qt 5.8.0, creating in in the dialog creating element, I running this on Linux Mink KDE 18.1.
The problem happens if I call settext() directly from the lineedit, if I set it calling the slot function directly within the class in which it exists and if I signal it from another class. I have tried all the applicable options in all the places I could, tried them and where they worked they all worked and where they didn't none did.
It works correctly elsewhere in the program, both before and after the calling of the task class and I always get the right answer displayed by the qDebug statement even if it doesn't update the text in the line edit correctly. When the files are being copied the progressbar works exactly as expected using the signals and slots from the same class.
I have a class that carries out a task for me (I'm trying to avoid the word process as I'm not running anything as a QPrpcess and want to avoid confusion - treat the work task as carrying out as series of steps to achieve something), that uses signals and slots to update the dialog box so the user knows the stage the program is at.
What the program is actually doing is scanning a folder structure finding all the instances of graphics files, with a a couple of different naming conventions and then copying them elsewhere to a single folder renaming them based on the folder structure from which they originate and the naming of the file. The dialog gives options, such as deleting all the files in the target folder at the start and of replacing or leaving existing files.
When it starts the LineEdit is set by the dialog class to display "Ready" within the dialog constructor and it works..
The user then clicks the button, which tells the task class (which was dynamically created in the dialog constructor) to start the task.
I have tried sending the "Building File List" QString to the line edit, both before calling the start task method and from within the class using the signal and slot. The "Building File list" status never gets displayed, though it gets displayed by qDebug and if I alter the code to send it at any other stage during the program, when I would have sent a different message it works then. within the task it using the same signal and slot updates the status to "copying" without any problem and using a different signal and slot to say that it is Finished and has copied a number of files.
I have tried 'Clean All', 'Rebuild All', 'Run QMake', restarted Qt Creator, the computer, stepping through it with the debugger and googling problems with line edit and I can't find anything that relates to this. I also tried clear() and insert() and neither of them work for this.
namespace CB_status { enum Current_Status { READY = 0, BUILDINGLIST = 1, COPYING = 2, DELETING = 3 }; const QStringList status_list { "Ready", "Building File List", "Copying Files", "Deleting Files" }; }
From Dialog Header file:
private slots: void recieve_status_update(int);
From Dialog Source File:
Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog), m_close_down(false), m_delete_all(false), m_replace_all(false), m_files_in_target(0) { ui->setupUi(this); setWindowTitle("Album Cover Backup"); setWindowIcon(QIcon(":/icons/ModernXP-54-Folder-Backup-Scheduled-icon.png")); this->ui->progressBar->setValue(0); m_Settings = new QSettings(tr("MikeOSoft"), tr("Album Cover Backup")); recieve_status_update(CB_status::Current_Status::READY); this->ui->lineEdit_information->clear(); read_Config(); this->ui->lineEdit_source->setText(m_source_path); this->ui->lineEdit_target->setText(m_output_path); this->ui->checkBox_replace_all->setChecked(m_replace_all); this->ui->checkBox_Delete_all->setChecked(m_delete_all); this->ui->checkBox_Shutdown->setChecked(m_close_down); m_backup = new AlbumArt_Backup(m_source_path, m_output_path, m_replace_all); QObject::connect(this->ui->checkBox_replace_all, SIGNAL(clicked()), this, SLOT(checkbox_state())); QObject::connect(this->ui->checkBox_Delete_all, SIGNAL(clicked()), this, SLOT(checkbox_state())); QObject::connect(this->ui->checkBox_Shutdown, SIGNAL(clicked()), this, SLOT(checkbox_state())); QObject::connect(m_backup, SIGNAL(send_progress_value(int)), this, SLOT(recieve_progress_update(int))); QObject::connect(m_backup, SIGNAL(send_status_value(int)), this, SLOT(recieve_status_update(int))); QObject::connect(m_backup, SIGNAL(send_finshed_value(int)), this, SLOT(recieve_finished_update(int))); QObject::connect(m_backup, SIGNAL(send_target_count(int)), this, SLOT(recieve_files_tocopy(int))); } void Dialog::on_pushButton_start_clicked() { // this->ui->lineEdit_information->clear(); // doesn't work // this->ui->lineEdit_status->setText("first"); // doesn't work // recieve_status_update(CB_status::Current_Status::BUILDING_LIST); // doesn't work if((!m_source_path.isEmpty()) && (!m_output_path.isEmpty())) { this->ui->progressBar->setValue(0); if(m_delete_all) { delete_files(); } m_files_in_target = countFiles(m_output_path); // recieve_status_update(CB_status::Current_Status::BUILDING_LIST); // doesn't work m_backup->start_process(); // recieve_status_update(CB_status::Current_Status::BUILDING_LIST + 1); //works - the plus one is just to make it show something different. if(m_close_down) { shutdown(); } } else { QMessageBox::warning(this, "Album Cover Backup", "You must select both a Source and a Target folder before you can run this application!", QMessageBox::Ok); } } void Dialog::recieve_status_update(int value) { QString test(CB_status::status_list[value]); qDebug() << test; // Always displays what I would expect this->ui->lineEdit_status->setText(test); // this->ui->lineEdit_status->setText(CB_status::status_list[value]); }
From Task class header file:
signals: void send_finshed_value(int newvalue); void send_progress_value(int newvalue); void send_status_value(int newvalue); void send_target_count(int newvalue);
From Task class file:
void AlbumArt_Backup::start_process() { emit send_status_value(CB_status::Current_Status::BUILDINGLIST); // This is what doesn't work QDirIterator it(m_source_location, QDirIterator::Subdirectories); while(it.hasNext()){ it.next(); if(it.fileName().contains(QRegExp("(\\w+)\\.(jpg|jpeg|png)$", Qt::CaseInsensitive))){ if(it.fileName().contains(QRegExp("(folder|cover|disc_)", Qt::CaseInsensitive))){ if(!it.filePath().contains("/Info/", Qt::CaseInsensitive)){ QString current_source = it.filePath(); QString current_target = build_file_name(current_source); m_all_existing_files.append(current_source); QFile Fout(current_target); if(!Fout.exists() || m_replace_existing) { m_file_list.insert(current_source, current_target); } } } } } emit send_target_count(m_file_list.size()); m_all_existing_files.sort(); filesize_list(); emit send_finshed_value(make_copies()); // Tell Dialogue list it's finished }
I code for fun and some am quite capable of doing something stupid, but I'm very puzzled as to why this isn't working, so any suggestions would be appreciated.
-
Hi,
start_process
contains a long running blockingwhile
hence it's blocking the application event loop so your QLineEdit updates will not happen until it's over. -
If the while loop is blocking the Event loop and it stops it from working whether I make the signal in the start_process() method within the album_art_backup class or from the pushbutton_start_clicked() method within the Dialog class, which gives a little more time (in computer terms) to do it before the while loop starts, what can I do to prevent the blocking from happening?
The Slot that responds to the signal is able to output the message using qDebug() and I get the same situation if I step through the code in the debugger, would the while loop do the same even in that situation?
I also have no problem updating the progressbar from the foreach loop that copies the files.
Do you have any suggestion as to how I can get around this, I wanting to let the user know that something is happening while the list of files is being built by the loop which you suggest is the problem?
Thank you for your assistance so far any further help would be appreciated.
-
The
qDebug
about doesn't depend on the event loop so you'll be seeing it anyway.When you have a long running operation and you don't want to block the GUI, you usually move that operation to a helper thread.