Unresponsive GUI while append text to QTextedit
-
Hello folks, i have a newbie question about QT C++. I have stringlists vector and i need to show them to users via qtextedits in stackedwidget. But because of too many stringlists, ui is freezing. I couldnt manage to do it with threading. Can you help me?
// widget header
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QDebug>
#include <QTreeWidgetItem>
#include <QVector>
#include <QRandomGenerator>
#include <QProgressDialog>
#include <QTextEdit>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_treeWidget_itemClicked(QTreeWidgetItem *item);
private:
Ui::Widget *ui;
void addTreeRoot(QString name);
void addTreeChild(QTreeWidgetItem *parent, QString name2);
void addPeriodTree();
void fillResultVector();
void fillResultStringList();
void setInterface();
int iCount;
int jCount;
int periodNo;
QVector<QVector<QVector<int>>> resultVector;
QVector<QStringList> resultStringLists;
QVector<QTextEdit *> summariesTextEdits;
QVector<QTextEdit *> resultsTextEdits;
};
#endif // WIDGET_H
// widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
ui->treeWidget->setHeaderHidden(true);
iCount = 120;
jCount = 137;
periodNo = 8;
fillResultVector();
fillResultStringList();
setInterface();
}
Widget::~Widget()
{
delete ui;
}
void Widget::addTreeRoot(QString name)
{
// QTreeWidgetItem(QTreeWidget * parent, int type = Type)
QTreeWidgetItem *treeItem = new QTreeWidgetItem(ui->treeWidget);
// QTreeWidgetItem::setText(int column, const QString & text)
treeItem->setText(0, name);
addTreeChild(treeItem, "Summary");
addTreeChild(treeItem, "Result");
}
void Widget::addTreeChild(QTreeWidgetItem *parent, QString name2)
{
// QTreeWidgetItem(QTreeWidget * parent, int type = Type)
QTreeWidgetItem *treeItem = new QTreeWidgetItem();
// QTreeWidgetItem::setText(int column, const QString & text)
treeItem->setText(0, name2);
// QTreeWidgetItem::addChild(QTreeWidgetItem * child)
parent->addChild(treeItem);
}
void Widget::addPeriodTree()
{
for (int i = 0; i < periodNo; i++)
{
addTreeRoot("Period " + QString::number(i + 1));
}
}
void Widget::on_treeWidget_itemClicked(QTreeWidgetItem *item)
{
if(item->parent())
{
qint16 pageNo = ui->treeWidget->indexOfTopLevelItem(item->parent()) * 2;
pageNo += item->parent()->indexOfChild(item);
ui->stackedWidget->setCurrentIndex(pageNo);
}
else
{
if(item->isExpanded())
{
item->setExpanded(false);
}
else
{
item->setExpanded(true);
}
}
}
void Widget::fillResultVector()
{
resultVector.resize(periodNo);
for (int p = 0; p < periodNo; p++)
{
resultVector [p].resize(iCount);
for (int i = 0; i < iCount; i++)
{
resultVector [p][i].resize(jCount);
}
}
for (int p = 0; p < periodNo; p++)
{
for (int i = 0; i < iCount; i++)
{
for (int j = 0; j < jCount; j++)
{
auto value = static_cast<unsigned long>(QRandomGenerator::global()->bounded(100));
resultVector [p][i][j] = value;
}
}
}
}
void Widget::fillResultStringList()
{
for (quint16 p = 0; p < periodNo; p++)
{
QStringList tempStrList;
resultStringLists.append(tempStrList);
for (int i = 0; i < iCount; i++)
{
QString tempStr1 = "";
QString tempStr2 = "";
for (int j = 0; j < jCount; j++)
{
QString tempStr2 = "";
tempStr2.setNum(resultVector.at(p).at(i).at(j));
tempStr2 = tempStr2.rightJustified(3, ' ');
tempStr1 += tempStr2;
}
tempStrList.append(tempStr1);
}
resultStringLists [p] = tempStrList;
}
}
void Widget::setInterface()
{
QProgressDialog progress("Preparing Interface...", QString(), 0, periodNo, this);
progress.setWindowModality(Qt::WindowModal);
addPeriodTree();
for (int p = 0; p < periodNo; p++)
{
progress.setValue(p);
if (progress.wasCanceled())
break;
QTextEdit *textEdSummary = new QTextEdit;
textEdSummary->setLineWrapMode(QTextEdit::NoWrap);
summariesTextEdits.append(textEdSummary);
QTextEdit *textEdPlan = new QTextEdit;
textEdPlan->setLineWrapMode(QTextEdit::NoWrap);
resultsTextEdits.append(textEdPlan);
summariesTextEdits [p]->setHtml("<span style='color: blue'><b>Summary</b> </span> <i>Qt!</i> " + QString::number(p + 1));
for (int i = 0; i < iCount; i++)
{
QString temp = resultStringLists.at(p).at(i);
resultsTextEdits [p]->append(temp);
}
ui->stackedWidget->addWidget(summariesTextEdits.at(p));
ui->stackedWidget->addWidget(resultsTextEdits.at(p));
}
progress.setValue(periodNo);
}
//widget.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Widget</class>
<widget class="QWidget" name="Widget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>534</height>
</rect>
</property>
<property name="windowTitle">
<string>Widget</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<widget class="QTreeWidget" name="treeWidget">
<property name="maximumSize">
<size>
<width>150</width>
<height>16777215</height>
</size>
</property>
<column>
<property name="text">
<string notr="true">1</string>
</property>
</column>
</widget>
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>-1</number>
</property>
</widget>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui> -
In that case a QTableView ?
-
@SGaist What is benefit of using QTableView here? There will be more than 1 matrix in the result. So user can select them from treewidget. I can change widget if they help me. If you are available, can you run my project to understand me better please.
-
How exactly do you want show these matrices ?
-
@SGaist In fact, the codes I have given are simplified versions of the project. In real project codes, there are slow operations at other thread. Slow operation iteration counts changing depending on user inputs. I call these operations as periods. Each periods have a result of matrix. In the main window result screen there should be period list and when user clicking one of these periods, the result of that period should be shown as matrix.
-
Well, storing and rendering are two different things.
Nothing stops you from having one matrix per cell.
-
How fast are you are you appending them ?
How big is your text ?
From how many sources do you do that ? -
- My data is ready to append. So i append them directly.
- There are 10-100 QTextEdits. I append 100-200 line to each of QTextEdits. Lines have arround 300 characters.
- I have one vector of vectors source.
By the way, i moved my data source to a different thread. Then emitted signals to append with BlockingQueuedConnection. Gui is responsive now. But its not smooth. I dont know using blockingqueuedconnection instead of queuedconnection is the right way but my gui is responsive while appending strings now.