Создайте всплывающее окно в QT без тени

Проще понять, что делает код не поточно-ориентированным. Есть две основные проблемы, которые приведут к тому, что многопоточное приложение будет иметь нежелательное поведение.

  • Доступ к общей переменной без блокировки
    Эта переменная может быть изменена другим потоком во время выполнения функции. Вы хотите предотвратить это с помощью механизма блокировки, чтобы быть уверенным в поведении вашей функции. Общее эмпирическое правило заключается в том, чтобы сохранить блокировку на максимально короткое время.

  • Дедлок, вызванный взаимной зависимостью от общей переменной
    Если у вас есть две общие переменные A и B. В одной функции вы сначала блокируете A, а затем блокируете B. В другой функции вы запускаете блокировка B и через некоторое время вы блокируете A. Это потенциальная тупиковая ситуация, когда первая функция будет ожидать разблокировки B, когда вторая функция будет ожидать разблокировки A. Эта проблема, вероятно, не будет возникать в вашей среде разработки и только время от времени. Чтобы избежать этого, все блокировки всегда должны быть в одном и том же порядке.

7
задан 30 June 2009 в 00:27
поделиться

2 ответа

Я думаю, что тень, которую вы видите, связана с темой Windows, которую вы используете. Здесь я использую классическую тему Windows, и я не вижу никаких теней :)

В любом случае, что, если вы подключите СИГНАЛ textChanged () QLineEdit к настраиваемому действию, которое восстанавливает фокус главного окна? Примерно так:

void PopupTest::handleClick()
{
   QFrame* popup1 = new QFrame(this, Qt::Tool | Qt::Window | Qt::FramelessWindowHint);
   popup1->resize(150,100);
   QLineEdit *tmpE = new QLineEdit( popup1 );
   connect( tmpE, SIGNAL( returnPressed() ), popup1, SLOT( hide() ) );
   connect( tmpE, SIGNAL( textChanged(const QString&)), this, SLOT( setActive() ) );
   tmpE->setGeometry(10,10, 130, 30);
   tmpE->setFocus();
   popup1->show();
}

void MainWindow::setActive()
{
   this->activateWindow();
}

Вам нужно будет создать слот с именем setActive (), и вы также должны поместить QLineEdit в заголовок вашего класса, чтобы с помощью функции setActive () вы могли сделать что-то вроде:

tmpE->setFocus();

, чтобы восстановить фокус на QLineEdit также.

2
ответ дан 6 December 2019 в 21:18
поделиться

Я разработал решение вопроса, который я опубликовал ранее.

Во-первых, всплывающий виджет может быть создан на основе QWidget с флагами Qt: : Окно | Qt :: FramelessWindowHint . На самом деле я взломал qwidget_win.cpp , чтобы убедиться, что мое окно имеет тот же стиль и расширенный стиль, что и элемент управления Popup, предоставляемый WPF (0x96000000 и 0x08000088 соответственно), как определено с помощью Spy ++, однако я не думаю, что это должно имеет значение.

Установка стиля окна не решает проблему активации окна. Ключ к этому - перехват сообщений Windows, информирующих главное окно о том, что его неклиентская область должна быть обновлена ​​(сообщение WM_NCACTIVATE ). Это можно сделать, предоставив собственную реализацию QApplication :: winEventFilter (MSG * msg, long * result) .

К сожалению, просто съесть инактивировать сообщения WM_ NCACTIVATE недостаточно, потому что это, похоже, предотвращает WM_ACTIVATE и другие сообщения, которые в противном случае генерируются из отправляется во всплывающее окно. Чтобы решить эту проблему, у меня есть доказательство работоспособности концепции, в которой я генерирую требуемые сообщения Windows в winEventFilter после того, как перехватил соответствующее сообщение WM_NCACTIVATE .

Отсюда есть некоторые детали поработать, чтобы убедиться, что он устойчив (на ум приходит перехват WM_ACTIVATEAPP ), а затем завернуть его во что-нибудь красивое и многоразовое.

Все это, конечно, зависит от Windows, интересно посмотреть, есть ли проблемы в Linux.

Все это немного больно. Надеюсь, я не пропустил ничего очевидного.

6
ответ дан 6 December 2019 в 21:18
поделиться
Другие вопросы по тегам:

Похожие вопросы: