“This is the fourth day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”

People who have done C++ development know that whether it is MFC framework or QT framework, the implementation of load data waiting effect is very troublesome, unlike the WEB side of the easy one line of code. For those of us who do C++, the most common way is to open threads.

At first, I also used the open thread approach, but imagination always contradicts reality.

Assume that the page displays a lot of data, resulting in a long time to load the page, the user experience is poor, click the trigger button after a long time will respond, always make people think that the program crashed, but the real reason is that the data is loading.

So, the current page shows a large amount of data, how do we dynamically display while loading data while displaying the page?

For me this just from the MFC framework turned over to the novice, it is indeed a no small challenge!

So, let me show you how I did it!

Step 1: Define display timer

To load data as soon as the page opens, we need to override the QWidget::show(), start the timer, and execute it immediately.

1: Defines a timer

//.h #include <QTimer> QTimer *m_Timer; //.cpp uses m_Timer = new QTimer(this); connect(m_Timer, &QTimer::timeout, this, &QMyWidget::OnTimerLoadData);Copy the code

2: the timer is invoked

void QMyWidget::show()
{
    QWidget::show();
    m_timer->start(0);
}
Copy the code

If the start parameter is 0, the timer operation must be started immediately.

At this point, the display page has loaded.

Because as mentioned before, the amount of data on the page is relatively large, and it is impossible to display the page in a state of suspended animation, so we need to load the page at the same time, display a GIF waiting icon.

Here, we need to modify the show() function

void QMyWidget::show() { QWidget::show(); GPageManager ::instance()->GetDownloadDlg()->SetShowMode(1); GPageManager :: Instance ()->GetDownloadDlg()->SetTips(" Loading case data, please wait..." ); gPageManager::instance()->GetDownloadDlg()->show(); if (m_timer->isActive() == false) { m_timer->start(0); }}Copy the code

Here, I use a singleton class: gPageManager calls a window with GIF renderings.

This way can be realized, after the display of the page, directly wait for the data load, prevent us to see the fake dead page, to the user caused trouble.

The GIF image here is hosted by a QLabel, and there are many ways to do this, but I won’t go into details.

Note: When using QT timers, it is safer to determine whether the timer is active or not, and only triggers when it is inactive. Here only do warm tips oh, personal code habits ~

3: The timer loads data

After entering the timer, data processing is carried out. In order to prevent the page from stalling, we also need to restart a thread in the timer for data loading.

At this point, one might ask, why create a thread when the current page already has a timer on?

I’m going to answer them all.

In C language functions, when the content of the specified function is run, the run page will not be displayed until “}” is run. The computer belongs to a process-handling function in a particular concrete processing function.

Therefore, it will open the timer operation on a display page, first show the page to the user, and do other data processing.

So why start another thread in the timer?

The main reason is that a dynamically loaded window is called in the show function. Assume that when a lot of data is directly loaded in the timer, the interface will also be stuck, resulting in the GIF waiting window being stuck. To prevent this, we need to continue a thread in the timer to prevent the page from stalling.

Void QMyWidget: : OnTimerLoadData () {/ / because just when open the page load data, so, only needs a timer. m_Timer->stop(); // Start the thread and load the data. GPageManager ::instance()->GetDownloadDlg()->hide(); }Copy the code

At this point, the ability to open the page and show the load directly is complete, so how to implement the current thread?

Next, is our second stage of content ~

2: The thread loads data

The normal C++ programmer, when confronted with this situation, usually naturally wants to use threads.

In fact, my first idea was to use threads to load data. However, the use of threads must take into account the disadvantages of threads, such as deadlocks, such as the occurrence of wild Pointers and other problems.

There is a simple way to start a thread in QT, which I recommend: QtConcurrent::run

The specific explanation of this function is not explained here, we directly use it!

The first required header file:

#include <QtConcurrent/QtConcurrentRun>
Copy the code

Next is the call method, where we define a function to load data called LoadWidgetData()

QFuture<bool> futureResult = QtConcurrent::run(this, &QMyWidget::LoadWidgetData); while (! futureResult.isFinished()) { QApplication::processEvents(QEventLoop::AllEvents); }Copy the code

When using this thread approach, note that the LoadWidgetData function must return true

Bool QMyWidget: : LoadWidgetData () {/ / specific data load operation return true; }Copy the code

The thread loading method has been introduced, at this point, we can implement a load data, a display wait GIF effect.

Next, how to display the loading progress in real time

3: Real-time display of loading progress

As we all know, there is no way to call page manipulation content in QT threads.

Normal page operations, such as window creation, control assignment, and so on, need to be done in the main thread, otherwise it will cause crash problems. Specific reason everybody can consult data to go.

So what do we do when we want to load data and display it on the page?

In this case, we can send messages in the thread to the main process to handle page operations

Bool QMyWidget: : LoadWidgetData () {/ / 1:1 load data content, concrete implementation not contents corresponding page 1 / / send data processing operations emit Msg_SendSelfDataProcessing1 (); / /... Return true; Return true; }Copy the code

The code looks easy to understand, which ensures smooth data loading without causing stuttering on the main page.

That’s the end of today’s update

If there are problems, we can learn from each other and make progress together!

‘!!!!!