LINUX.ORG.RU

Kill QThread


0

2

Здравствуйте! Нужно убить поток QThead. В документации написано, что делается это с момощью QEventLoop, но толком не описано как... Подскажите пожалуйста.

class MyThread(QtCore.QThread):
    def __init__(self, parent=None):
        QtCore.QThread.__init__(self, parent)
    def run(self):
        print "do something"

class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
    def __init__(self):
        QtGui.QMainWindow.__init__(self)
        self.setupUi(self)
        
        self.thread = MyThread()       
        self.connect(self.pushButton, QtCore.SIGNAL(_fromUtf8("clicked()")), self.thread.start)
        self.connect(self.pushButton2, QtCore.SIGNAL(_fromUtf8("clicked()")), self.thread.exit)


> self.thread.exit
exit не является слотом, quit является.

rival ★★
()
Ответ на: комментарий от one_more_hokum

Меня смущает:

«Warning: This function is dangerous and its use is discouraged.In short, use this function only if absolutely necessary.»

И что тогда делают exit и quit?

r3m1x
() автор топика
Ответ на: комментарий от rival

[code] class MyThread(QtCore.QThread): def __init__(self): QtCore.QThread.__init__(self) def run(self): import make_it make_it.do_it() [/code] В потоке запускается функция, после вызова quit, она все-равно продолжает работать...

r3m1x
() автор топика
Ответ на: комментарий от r3m1x

run по дефолту вызывает exec()

int QThread::exec()
{
    // bla-bla-bla
    QEventLoop eventLoop;
    int returnCode = eventLoop.exec();
    // bla-bla-bla
}
quit это слот, который вызывает exit(0), exit же завершает eventloop:
void QThread::exit(int returnCode)
{
    // bla-bla-bla
    for (int i = 0; i < d->data->eventLoops.size(); ++i) {
        QEventLoop *eventLoop = d->data->eventLoops.at(i);
        eventLoop->exit(returnCode);
    }
}
Точнее даже все eventloop'ы, привязанные к данному потоку.

Если у тебя run переопределен, то возможно у тебя и нет никаких eventloop'ов, а следовательно quit и exit ничего не делают (почти).

rival ★★
()
Ответ на: комментарий от r3m1x

Функция судя по всему не знает о существовании треда, разумеется quit тут не поможет, так как у тебя нет eventloop'а, а также внутри run'а и этой функции do_it нигде не проверяется хочет ли поток завершиться или нет.
Я как я понимаю, terminate ничего не гарантирует и является плохой практикой, но применяется именно в таких ситуациях.

Почитай:
http://diotavelli.net/PyQtWiki/Threading,_Signals_and_Slots
Вдруг поможет.

rival ★★
()
Ответ на: комментарий от r3m1x

> И что тогда делают exit и quit?

По хорошему, после выполнения всех нужных/ненужных действий в функции run (переопределённой тобой), нужно вызвать функцию exec, которая будет крутить цикл сообщений, и ожидать прерывания. Прерывание и делается exit-ом (функция) или quit-ом (слот). Хотя лично мне реализация потоков в Qt кажется безобразно корявым.

one_more_hokum ★★★
()
Ответ на: комментарий от anonymous

Как пример, используя boost::thread + boost::bind я могу зацепить поток на функцию класса, передав ей сразу же нужное количество аргументов. И не надо наследоваться от всяких QThread, переопределять метод run, который не принимает параметров, и надо плясать с бубном, чтобы что-нить ему отдать.

one_more_hokum ★★★
()
Ответ на: комментарий от anonymous

Когда я начинал работать с Qt, этого ещё не было. А в boost-е всё уже было. И futures тоже были.

one_more_hokum ★★★
()
Ответ на: комментарий от one_more_hokum

И не надо наследоваться от всяких QThread, переопределять метод run

Почитай известную статью по теме: http://labs.qt.nokia.com/2010/06/17/youre-doing-it-wrong/

Для Ъ, «правильная» многопоточность, начиная с Qt 4.4, делается примерно так:

QThread *thread = new QThread;

MyObject *object = new MyObject; // MyObject is QObject's descendant
object->moveToThread(thread);

connect(thread, SIGNAL(started()), object, SLOT(start()));
thread->start();

я могу зацепить поток на функцию класса, передав ей сразу же нужное количество аргументов

Про QtConcurrent уже сказали

anonymous
()
Ответ на: комментарий от one_more_hokum

> Я уже упоминал, что начинал «слегка» раньше.

Ну так и скажи, «последние 3 года Qt не трогал», например. Заявления о «корявости» только сбивают с толку начинающих.

anonymous
()
Ответ на: комментарий от anonymous

Один хрен, работа с потоками в Qt реализована хуже, чем в том же boost-е. А всякие извращения, потребные для того, чтобы из потока дёрнуть чей-нить слот (привет QMetaObject::invokeMethod) вообще могут в страшных снах сниться.

one_more_hokum ★★★
()
Ответ на: комментарий от one_more_hokum

> Один хрен, работа с потоками в Qt реализована хуже, чем в том же boost-е

Давай пример какой-нибудь. Может ты и прав, конечно, но пока твои заявления совершенно ни о чем.

А всякие извращения, потребные для того, чтобы из потока дёрнуть чей-нить слот

Обычный QObject::connect() прекрасно справляется c кросс-поточным «дерганьем» слотов.

привет QMetaObject::invokeMethod

Заодно покажи, как задача, которая выполняется с помощью QMetaObject::invokeMethod(), решается в бусте. Ведь ты же знаешь, о чем говоришь.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.