Nano Hash - криптовалюты, майнинг, программирование

QMainWindow - дождаться завершения функции "show"

Есть ли сигнал, который сообщает, когда заканчивается функция «show»?

У меня проблема в моем коде: если я пишу:

QMainWinObj.show();
QMainWinObj.someGuiFunc();

код не работает. Но если я напишу:

QMainWinObj.show();
sleep(3000);
QMainWinObj.someGuiFunc();

Оно делает.

Поэтому я думаю, что проблема в том, что «шоу» не заканчивает свою работу до того, как я вызову «someGuiFunc». Вот почему я хочу иметь какой-то знак того, что «шоу» окончено..

08.04.2013

  • Здесь важно знать, что вы пытаетесь сделать. Какова ваша конечная цель? Что делает someGuiFunc()? 08.04.2013
  • Я согласен с @JanKundrát, с чего бы someGuiFunc() полагаться на видимость QMainWinObj? Даже если бы он полагался на отрисовку, someGuiFunc() просто нужно было бы дождаться очистки очереди событий (есть несколько простых способов сделать это), но в этом случае второй пример все равно не работал бы, потому что sleep останавливается. текущий поток. 08.04.2013

Ответы:


1

Это может быть немного устаревшим, но поскольку никто другой не ответил на него, кроме одного: Поскольку нет сигнала «Показать», я предлагаю переопределить событие показа следующим образом:

В вашем файле mainwindow.cpp:

void MainWindow::show()
{
   QMainWindow::show();
   QApplication::processEvents();
   emit windowShown();
}

В вашем файле mainwindow.h где-то в объявлении MainWindow:

...
class MainWindow: public QMainWindow
{
   ...
   signals:
       void windowShown();

   ...
}
...

Затем, когда вы перейдете в дизайнер, щелкните правой кнопкой мыши в главном окне (самая верхняя часть дерева объектов) и выберите «Изменить сигналы/слоты». В кадре «Сигналы» нажмите кнопку «+», и вам нужно будет добавить «windowShown()», а затем нажать клавишу ввода, а затем кнопку «ОК» (обратите внимание, что многоточие «...» обозначает другой код, который уже в шапке).

Вот и все - теперь вы можете использовать редактор сигналов/слотов, чтобы связать слоты с сигналом 'windowShown', когда захотите. Теперь, если вы хотите что-то более похожее на событие Microsoft "Loaded", которое, как я думаю, используется в .NET, вам нужно будет создать некоторую переменную экземпляра и пометить ее, чтобы каждый раз, когда отображается окно, оно не испускалось, например:

void MainWindow::show()
{
   QMainWindow::show();
   QApplication::processEvents();
   emit windowShown();
   if (firstTimeShown == true)
   {
      emit windowLoaded();
      firstTimeShown = false;
   }
}

Кроме того, не забудьте инициализировать переменную значением «true» в вашем конструкторе:

MainWindow::MainWindow(QObject* parent)
 ...
{
   firstTimeShown = true; // put this somewhere before ui->setupUi()
}

Однако, если вы решите поместить его в список инициализаторов, убедитесь, что он находится в правильном порядке. Компилятор будет жаловаться, если переменные не создаются сверху вниз, как объявлено в заголовке класса.

Теперь убедитесь, что когда вы определяете firstTimeShown в своем заголовке, вы делаете его приватным. И давайте не будем забывать о добавленных сигналах:

class MainWindow : public QMainWindow
{
    ...
    signals:
      void windowLoaded();
      void windowShown();

    private:
      bool firstTimeShown;
    ...

Вот об этом. Благодаря гибкости сигналов и слотов довольно легко имитировать любое событие, которое вы можете найти в формах Windows или в MFC. Это просто требует немного усилий со стороны программиста. Как только вы освоитесь, это станет второй натурой.

примечание: вероятно, существуют существуют оптимизации или лучшие и более точные способы заставить работать сигналы "Loaded" и "Shown", но я оставил такие вещи для простоты. И чтобы вернуться к заданному вопросу, вызов QApplication::processEvents(), скорее всего, то, что вы хотите сделать вместо ожидания фиксированного времени, потому что кто знает, сколько времени это займет, если пользователь запускает 100 других вещей на вдобавок к этому и т. д. и т. д. Надеюсь, что это помогло, дополнительное объяснение было включено в надежде, что оно может дать вам лучший способ делать то, что вы хотите сделать, вместо того, чтобы ждать, пока что-то будет сделано, «зная», что это сделано является гораздо лучшей альтернативой.

22.12.2013

2

Такого сигнала нет, но имея подкласс QMainWindow, вы можете переопределить событие showEvent.

void MainWindow::showEvent(QShowEvent *){
    //your code
}

Дополнительная информация здесь: http://qt-project.org/doc/qt-4.8/qwidget.html#showEvent

Имейте в виду, что он вызывается каждый раз, когда ваше окно собирается отображаться.

08.04.2013

3

Проблема может быть решена без подкласса, просто установив фильтр событий следующим образом:

class CWidgetIsPainting_EF : public QObject
{
    bool m_bIsPainted = false;
public:
    CWidgetIsPainting_EF( QObject * parent = 0 ) : QObject (parent) { }

    inline bool IsPainted() const { return m_bIsPainted; }
    inline void setIsPainted( bool bIsPainted ) { m_bIsPainted = bIsPainted; }

protected:
    bool eventFilter( QObject * obj, QEvent *event )
    {
        if (event->type() == QEvent::Paint)
        {
            m_bIsPainted = true;
            return true;
        };
        return QObject::eventFilter(obj, event);
    }
};

... ...

CWidgetIsPainting_EF * pPaintingEF = new CWidgetIsPainting_EF( m_pWidget );
m_pWidget->installEventFilter( pPaintingEF );

... ...

while ( !pPaintingEF->IsPainted() )
    QApplication::processEvents();
06.07.2017

4

Переопределите bool event(QEvent *event) и поймайте событие Paint. У меня работает по крайней мере на винде.

// MainWindow.h
class MainWindow : public QMainWindow
{
    ...
    bool event(QEvent *event) override;
    void functionAfterShown();
    ...
    bool functionAfterShownCalled = false;
    ...
}

// MainWindow.cpp
bool MainWindow::event(QEvent *event)
{
    const bool ret_val = QMainWindow::event(event);
    if(!functionAfterShownCalled && event->type() == QEvent::Paint)
    {
        functionAfterShown();
        functionAfterShownCalled = true;
    }
    return ret_val;
}
27.09.2016
Новые материалы

Кластеризация: более глубокий взгляд
Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

Как написать эффективное резюме
Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

Частный метод Python: улучшение инкапсуляции и безопасности
Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

Как я автоматизирую тестирование с помощью Jest
Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..