Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / QT как из другого потока изменить свойство объекта формы? / 5 сообщений из 5, страница 1 из 1
04.05.2016, 19:53
    #39229444
Картежник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
QT как из другого потока изменить свойство объекта формы?
Для примера. есть две кнопки и два label (тексты = "0"). при нажатии на первую кнопку запускается цикл от 0 до 1000 например и при каждой итерации значение итерации выводится в первый Label. при этом если во время этого цикла нажать на вторую кнопку то значение второго Label должно увеличиться на 1 не дожидаясь пока закончится цикл.
сделал маленькую прогу, но выходит ошибка . при нажатии на первую кнопку

0
ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread b08f90. Receiver 'MainWindow' (of type 'MainWindow') was created in thread 1a95e8", file kernel\qcoreapplication.cpp, line 514
QObject::~QObject: Timers cannot be stopped from another thread

Код
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(this,SIGNAL(set_lab1(int)),this,SLOT(set_label1(int)));
}

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

void MainWindow::on_pushButton_clicked()
{
    QtConcurrent::run(this,&MainWindow::inc_lab1);
//inc_lab1();
}

void MainWindow::on_pushButton_2_clicked()
{
int n=ui->label_2->text().toInt();
ui->label_2->setText(QString::number(n+1));
}

void MainWindow::inc_lab1()
{
    for(int i=0;i<1000;i++){
        ui->label->setText(QString::number(i));
        qDebug()<<i;

        Sleep(10);
        this->repaint();
    }
}
...
Рейтинг: 0 / 0
04.05.2016, 19:58
    #39229447
Картежник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
QT как из другого потока изменить свойство объекта формы?
Картежник,

так пока все понятно надо было убрать this->repaint();

но надо попробовать по другому.потому что в оригинальной задаче(а там куча объектов, прогрессбары и т.д) это не проходит. попробую переформулировать задачу ближе к оригинальной задаче
...
Рейтинг: 0 / 0
04.05.2016, 20:09
    #39229452
Картежник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
QT как из другого потока изменить свойство объекта формы?
Картежник,
вообщем вот. кусок кода. удаляет файлы из списка list.xml. удаление работает, прогрессбары двигаются, но программа не реагирует на мои клики по другим элементам формы.
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
void GameCatalog::remove_game_thr(int num)
{
    qDebug()<<"remove_game";

    QString s="";
    if(gamesList[num]->installpath!="")
    {
        GameWidget *gam = (GameWidget*)qstack->widget(num);
        s=gamesList[num]->installpath;
        gam->ValidGame(5);
        gam->prog_text->setText("Удаление:");
        //----удаление торрента
        tor->stop_upload(gam,true);
        if((s!="")&&(!s.isEmpty())&&(s.length()>3))
        {
            connect(this,SIGNAL(set_prog_value(int,int)),this,SLOT(set_progress_value(int,int)),Qt::UniqueConnection);
            QFuture<void> func=QtConcurrent::run(this,&GameCatalog::remove_game,gamesList[num]->id,s,gamesList[num]->shortname);
        }
        gamesList[num]->installpath.clear();

        gam->ValidGame(1);
        save_gamepaths();  
    }

}


void GameCatalog::remove_game(int gid,QString s,QString shortname)
{

    QList <QString> list_s;
            QDir dir_path;
            dir_path.setPath(s);
            QFile *f=new QFile(qApp->applicationDirPath()+"/games/"+shortname+"/list.xml");
            f->open(QFile::ReadOnly);

            QByteArray cont=f->readAll();
            f->close();
            f->deleteLater();


            QList <QByteArray> allfiles =cont.split('\n');
            double allcount = allfiles.count();
            double countminus =allfiles.count();
            double perc=(countminus/allcount)*100;
            int percent=(int)perc;
            emit set_prog_value(percent,gid);
            //gamesList[num]->prog->setValue(percent);
            //gam->prog->setValue(percent);

            qDebug()<<"all files for remove  = "<<allfiles.count();
            for(int l=0; l<allfiles.count(); l++)
            {

                QDir *d=new QDir(allfiles[l]);
                if(d->exists())
                {
                    list_s.append(allfiles[l]);
                    delete d;
                    continue;
                }
                if(allfiles[l]!=""){
                    QFile::remove(allfiles[l]);
                }
                delete d;
                countminus--;
                perc=(countminus/allcount)*100;
                percent=(int)perc;
                emit set_prog_value(percent,gid);
              
                sleep(1);
            }

            qDebug()<<"sort";
            QString buf;
            for(int i=0;i<list_s.count();i++)
            {
                for(int j=0;j<list_s.count();j++)
                {
                    if(list_s[i]>list_s[j])
                    {
                        buf=list_s[i];
                        list_s[i]=list_s[j];
                        list_s[j]=buf;
                    }
                    sleep(1);
                }
            }
            for(int i=0;i<list_s.count();i++)
            {
                QDir *d=new QDir(list_s[i]);
                qDebug()<<"folder "<<list_s[i];
                if(list_s[i]!=""){
                    d->rmdir(list_s[i]);
                }
                delete d;
                countminus--;
                perc=(countminus/allcount)*100;
                percent=(int)perc;
                emit set_prog_value(percent,gid);
               
                sleep(1);
            }

            QFile::remove(qApp->applicationDirPath()+"/games/"+shortname+"/list.xml");

}
...
Рейтинг: 0 / 0
04.05.2016, 20:49
    #39229466
Гость123
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
QT как из другого потока изменить свойство объекта формы?
Картежник,

По правильному все долгие задачи должны запускаться не в потоке интерфейса, а в отдельном.
А если по простому, то надо вставить QApplication::processEvents() на каждую итерацию цикла в потоке интерфейса.
Хотя может у вас там сложный и неправильный вариант: отдельный поток запускается, а поток интерфейса блокируется ожиданием его завершения. Тогда всё грустно и надо переделывать.
...
Рейтинг: 0 / 0
04.05.2016, 21:05
    #39229470
Картежник
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
QT как из другого потока изменить свойство объекта формы?
Гость123,

переделал
на
connect(this,SIGNAL(set_prog_value(int,int)),this,SLOT(set_progress_value(int,int)),Qt::BlockingQueuedConnection);
и теперь заработало.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / QT как из другого потока изменить свойство объекта формы? / 5 сообщений из 5, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]