Проще понять, что делает код не поточно-ориентированным. Есть две основные проблемы, которые приведут к тому, что многопоточное приложение будет иметь нежелательное поведение.
Доступ к общей переменной без блокировки
Эта переменная может быть изменена другим потоком во время выполнения функции. Вы хотите предотвратить это с помощью механизма блокировки, чтобы быть уверенным в поведении вашей функции. Общее эмпирическое правило заключается в том, чтобы сохранить блокировку на максимально короткое время.
Дедлок, вызванный взаимной зависимостью от общей переменной
Если у вас есть две общие переменные A и B. В одной функции вы сначала блокируете A, а затем блокируете B. В другой функции вы запускаете блокировка B и через некоторое время вы блокируете A. Это потенциальная тупиковая ситуация, когда первая функция будет ожидать разблокировки B, когда вторая функция будет ожидать разблокировки A. Эта проблема, вероятно, не будет возникать в вашей среде разработки и только время от времени. Чтобы избежать этого, все блокировки всегда должны быть в одном и том же порядке.
Я думаю, что тень, которую вы видите, связана с темой 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 также.
Я разработал решение вопроса, который я опубликовал ранее.
Во-первых, всплывающий виджет может быть создан на основе 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.
Все это немного больно. Надеюсь, я не пропустил ничего очевидного.