Я работаю с QThread
и механизмом слотов/сигналов; Я знаю, что есть много тем по этому поводу в Интернете в целом и здесь, в SO, в частности, но я так и не смог найти решение. Во всяком случае, вот контекст.
Фрагмент кода, который я пытаюсь придумать, предназначен для управления через графический интерфейс длительным процессом, поэтому используется QThread
.
У меня есть окно с двумя кнопками, старт и стоп. У моего Window
также есть QThread
и Task
, где последний наследуется от QObject
. Я хочу иметь возможность остановить свою задачу во время ее выполнения и предотвратить ее повторный запуск, если нажата кнопка «Пуск», когда она уже запущена.
Вот отрывок из Task
(который имитирует долгий процесс):
class Task: public QObject
{
public:
Task(): QObject(), stop_(true) {}
private slots:
void startTask()
{
stop_ = false;
run();
}
void stopTask()
{
stop_ = true;
}
void run() const
{
while ( ! stop_)
{
sleep(1);
}
}
bool stop_;
};
Я сделал две связи между кнопками и задачей в конструкторе моего Window
:
class Window: public QWidget
{
public:
Window()
{
// Instantiate buttons and put them in a layout.
// ...
connect(buttonStart_, SIGNAL(clicked()), &task_, SLOT(startTask()));
connect(buttonStop_, SIGNAL(clicked()), &task_, SLOT(stopTask()),
Qt::DirectConnection);
task_.moveToThread(&thread);
thread_.start();
}
private:
QPushButton buttonStart_;
QPushButton buttonStop_;
QThread thread_;
Task task_;
};
Я использовал Qt::DirectConnection
во втором connect()
для того, чтобы "форсировать" обработку моего сигнала с запросом на остановку задачи, т.к. (как я понимаю) task_
нужно вернуться из своей работы перед дальнейшей обработкой событий (если я использую подключение по умолчанию, все мои клики обрабатываются после того, как моя задача «выполнена»).
Здесь Qt::DirectConnection
«обходит» очередь событий, и таким образом я могу остановить свою задачу. Но, честно говоря, я не знаю, правильный ли это способ сделать это или это обходной путь (поэтому, возможно, корень моей проблемы).
В любом случае, это работает нормально, но когда я начинаю играть с моими кнопками, графический интерфейс в конечном итоге зависает, и это моя проблема!
Любая помощь приветствуется; Спасибо за ваше время!