Re[8]: Создать окна в консольном приложении. Как?
От: Skorodum Россия  
Дата: 11.11.21 15:00
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Что значит, "изменим условние"? Название темы однозначно говорит о консольном приложении.

+1

BFE>Например, выход из приложения. Как корректно выйти из консольного приложения (с графическими окнами) ожидающего ввод пользователя при shutdown?

Установить обработчик на ctrl+c и спросить пользователья точно ли он хочет выйти

BFE>Проблемы могут быть связаны со скоростью: вывод в одно окно тормозит вывод во всех других окнах.

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

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

И? Взаимодействие пользователя с окнами не может сгенерировать хоть сколько-нибудь значительное количество сигналов.

BFE>Так же могут возникнуть проблемы при завершении отдельных потоков.

Если криво писать — то да, наверное, могут.
Re[3]: Создать окна в консольном приложении. Как?
От: fk0 Россия https://fk0.name
Дата: 12.11.21 23:44
Оценка:
Здравствуйте, imh0, Вы писали:

RW>>может, для визуальной части сделать отдельную gui-шную программу ненавистно висящую в трее? и пусть мониторит какой-нибудь файл в простейшем случае или обменивается с консольной по пайпу?


I>Нет тут, надо исходить и того, что такое как бы требование- надо чтобы было консольное приложене. На самом деле это библиотека и надо чтобы ее можно было использовать и в консольном приложении тоже. Все это под линукс, тут все горазло проще чем под виндой. То есть изначально нет разницы что это за приложение. Тут нет такого понятия как "подсистема" как в винде.


А что мешает установить X11 сессию, в нужный момент (а вдруг иксов не окажется, может лучше заранее?) и собственно отрисовать окно (второе, третье) когда нужно, а не на старте программы? В юниксе нет понятия "графическая программа" или "консольная" (как верно замечено, нет понятия подсистемы, как в виндах). Любая программа может сделать что угодно и когда попало.

Но практически, повторюсь, сессию начать наверное стоит на старте, и даже окна может быть создать сразу (чтоб потом не тупить). Просто делать эти окна видимыми по факту необходимости.
Re[2]: Создать окна в консольном приложении. Как?
От: fk0 Россия https://fk0.name
Дата: 12.11.21 23:51
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>гуй пускаеш в отдельном потоке и выдаёш ему подписку на источник данных.


Главное чтоб гуй случайно не стал многопоточным. Винда так может местами и может,
а X11 заклинит. Нет, что-то отослать (запрос на X11 сервер) ещё так можно, но ответы от сервера,
цикл обработки событий, неизбежно слушать нужно в одном потоке. На самом деле можно не в одном,
но синхронизироваться нужно и непонятно зачем тогда такое нужно. Читать иксовый сокет должен
строго один поток (ждать событий), да и писать одновременно не стоит (в сокете будет мешанина).

_>а консольное прложение пишет данные в этот самый источник.


Я бы просто в отдельном потоке запустил иксовую сессию, цикл обработки событий. И в нём
делал бы все гуёвые дела, событийным методом. И туда же накидывал события от негуёвых
частей системы.

_>С точки зрения архитектуры гуи и простое консольное не должны знать о существовании друг друга.


Да ладно. В виндах все всё знают и всё работает.
Re[5]: Создать окна в консольном приложении. Как?
От: fk0 Россия https://fk0.name
Дата: 12.11.21 23:55
Оценка:
Здравствуйте, imh0, Вы писали:

S>>Это настолько базавая и тривиальная вещь в Qt что непонятно, что тебе непонятно

S>>По существу ответил.
Автор: Skorodum
Дата: 11.11.21


I>Уверен, что вешь трвиальная, но тем не менее... По эвентам это значит я не контролирую процесс выполнения приложения. То есть процесс обработки каких-то внешних по отношению к QT событиям идет лесом.


А всё остальное пускаешь в отдельных потоках. И они накидываюют эвенты в гуёвый евент-луп если
им что-то от него нужно. А он в свою очередь их может пинать через их евент-лупы, если у них
есть, напрямую вызывать их функци и т.п.

I> А мне как раз и надо чтобы по какому-то внешнему событию создавались окна и также ассинхронно по отношению к QT они могли закрываться.


Асинхронно по отношению к графической системе не получится. Цикл на самом деле не в Qt, а в X11.
Т.е. на самом деле в X11 его нет, там только несколько функций которые нужно вызывать в цикле, а
цикл действительно внешний и в Qt, но работать вне цикла не получится вообще тем не менее.

I> Тут даже не главное закрывать окна, тут главное чтобы не было потери уравления в результате передачи управления в app.exec... Когда я сам диспечеризирую события QT то я могу также диспечеризировать внешние события.


В отдельных потоках. По крайней мере в ещё одном отдельном потоке, по меньше мере ещё одном.
Потому, что GUI будет блокироваться на 1) ожидании своих событий, 2) отрисовке.
Re[4]: Создать окна в консольном приложении. Как?
От: fk0 Россия https://fk0.name
Дата: 13.11.21 00:01
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Здравствуйте, imh0, Вы писали:


I>>Смотрите, вопрос по теме форума, вопрос не простой, вопрос на самом деле актуальный...

BFE>Вопрос слишком обширный и не понятно, чего хочет imh0.
BFE>Если он хочет несколько консольных окон в одном приложении с одним(!) запущенным процессом — то это не возможно.

С хера ли невозможно? Запускай 10 штук xterm'ов и каким-то образом передавай от них файл-дескрипторы, от slave-конца псевдотерминала себе в аппликацию. Через, например, некий мелкий процесс который тебе их, файл-дескрипторы, через сокет обратно вышлет, например. Только я посмотрел, это тебе даже не нужно, т.к. xterm имеет опцию -S, т.е. может рабоать с уже созданным тобой и существующим псевдотерминалом. В общем говно вопрос. У тебя в итоге десяток псевдотерминалов и пиши/читай в любой. Сам, без printf только.

BFE>Есть ещё вариант, обеспечивать окна внутри консоли (псевдографикой).


Для этого есть ncurses.
Re[9]: Создать окна в консольном приложении. Как?
От: fk0 Россия https://fk0.name
Дата: 13.11.21 00:07
Оценка:
Здравствуйте, Skorodum, Вы писали:

BFE>>Например, выход из приложения. Как корректно выйти из консольного приложения (с графическими окнами) ожидающего ввод пользователя при shutdown?

S>Установить обработчик на ctrl+c и спросить пользователья точно ли он хочет выйти

А если пользователь выходит по Ctrl-\ ? А если по Ctrl-Z и Ctrl-D, Ctrl-D ?
А если пользователь мышкой закрывает xterm в котором программа?
А если зашёл через ssh и тут интернет оборвался?
А если сисадмина обидели, он уволился и в кронтаб вставил kill -11 $RANDOM ?
Re[11]: Создать окна в консольном приложении. Как?
От: SaZ  
Дата: 13.11.21 10:43
Оценка:
Здравствуйте, imh0, Вы писали:

I>...

I>
I>Application a(argc, argv);
I>a.exec();
I>


I>Честно? Твой ответ вообще не по теме. Мне надо после a.exec() работать, ты мне привел пример того что и так ясно... Но я уже сказал — извини, но таким тоном можешь разговаривать дома. А лучше и там не надо.


Что именно нужно делать "после"? С точки зрения Qt ничего "после" быть не может. Если надо "после" — то в отдельном потоке. А лучше — вот этот весь код с QApplication в отдельный поток. Но я об этом уже писал выше.


S>>Тебе надо Qt хоть немного понять, и чтобы вопрос нормально сформулировать и чтобы ответы понимать.

I>Ага еще раз спасибо )

Если хотите абстрактно от Qt — то вы должны понимать и уметь реализовывать в многопоточной среде такие паттерны как chain of responsibility и producer consumer. Иначе все объяснения бесполезны.
Ваша проблема — вы не можете понять где вам проинициализировать обработчик. Об этом я тоже выше писал — надо понимать что у вас за события. Без этого не получится предметного разговора.

P.S. ко всем участникам темы — давайте не переходить на личности и оскорбления, а то достану банхаммер.

Очень псевдокод:
class Handler : public QObject
{
  Q_OBJECT
public:
  // ...
  void on_my_event()
  {
    QTimer::singleShot(0, this, &Handler::show_gui);
  }

  void show_gui()
  {
    // Создаём окно. Это уже будет вызвано в Qt потоке
  }
}

int qt_thread(conditional_variable& cv, Handler *h)
{
  QApplication app;
  h = new Handler;
  h->setParent(&app);
  cv.wake_all();
  return app.exec();
}

void main_thread()
{
  conditional_variable& cv;
  Handler *h = nullptr;

  std::thread t{&qt_thread, cv, h};
  cv.wait();

  // Прилетает сигнал - дёргаем наш прокси
  h->on_my_event();
}
Re[7]: Создать окна в консольном приложении. Как?
От: SaZ  
Дата: 13.11.21 10:46
Оценка:
Здравствуйте, Skorodum, Вы писали:

S>Здравствуйте, SaZ, Вы писали:


SaZ>>В любом случае всё сводится к следующему: создаётся отдельный поток в котором делается инстанс QApplication.

S>Обычно QApplication и все гуёвые события в основном потоке (собственно, QApplication::exec и стартуерт "main event loop"), а вот что-то типа работы с сетью — в отдельных потоках.

Там где-то проскакивало условие, что нужно из динамической библиотеки это делать. Всё сводится к тому, что считать "основным потоком". Если в Qt за последние 5 лет ничего не поменялось, то основной поток это тот, в котором инициализируются глобальные qtшные переменные и создаётся QCoreApplication. Делать это в разных потоках так себе идея, но у меня работало.
Re[12]: Создать окна в консольном приложении. Как?
От: imh0  
Дата: 14.11.21 15:12
Оценка: +1
Здравствуйте, SaZ, Вы писали:

SaZ>Ваша проблема — вы не можете понять где вам проинициализировать обработчик. Об этом я тоже выше писал — надо понимать что у вас за события. Без этого не получится предметного разговора.


Ага. Спасибо....

Но пока с Skorodum-умами пререкались, я все и сделал. Вроде архитектурно не плохо... Приводить код и подробно описывать неверное не имеет смысл, но кратко суть такая...

1) В main создаю поток через std::thread создаю поток П1.

2) В потоке П1 создаю обьект класс MYLIB отнаследованного от QApplication. В этом классе обьявленны сигналы и слоты CreateWindow, DestryWindow, и некоторыми функциями для вывода данных в окна.

3) В потоке П1 с помощью QObject::connect с транспортом через Qt::BlockingQueuedConnection, соединяю эти сигналы со слотами.

4) В потоке П1 через статический глобальный std::promise<MYLIB*> MyLib с помощью set_value устанавливаю значение для созданного в П1 обьекта.... Можно было ды обойтись и без глобальной переменной но мне это пока не критично.

5) В потоке П1 запускаю QT exec()... То есть QT поехала... )

5) В main через std::future <MYLIB*> на MyLib жду когда библиотека будет от-инициализирована в потоке П1.

6) В любой точке любого потока пользовательского кода, вызывается например функция (MYLIB*)->CreateWindow которая отрабатывает в SLOT соединенный с CreateWindow. И так как транспорт Qt::BlockingQueuedConnection то пока слот не отработает то пользовательский код висит и ждет.

То есть удалось сделать красиво — избежать диспечеризации событий, но при этом корректно вызывать создание окон из одного единственного потока. И блокировки X11 дисплея удалось избежать, и QT висит на своем exec() и все кросплатформенно.


Думал код тут выложить — там строк 200 вместе с двойной буферизацией черех QPIXMAP... Но думаю нет смысла, мало кому это покажеться интересным..
Отредактировано 14.11.2021 15:14 imh0 . Предыдущая версия .
Re[8]: Создать окна в консольном приложении. Как?
От: Skorodum Россия  
Дата: 15.11.21 08:15
Оценка:
Здравствуйте, SaZ, Вы писали:

SaZ>Там где-то проскакивало условие, что нужно из динамической библиотеки это делать.

Какая разница какая линкова? Это ничего не меняет
Потоки сторонней библиотеки оборачиваются в QThreaed, события прокидываются в основной поток через стандартные сигналы/слоты.
Re[3]: Создать окна в консольном приложении. Как?
От: удусекшл  
Дата: 15.11.21 08:43
Оценка:
Здравствуйте, imh0, Вы писали:

I>>>Как это все сделать с точки зрения архитектуры?


RW>>может, для визуальной части сделать отдельную gui-шную программу ненавистно висящую в трее? и пусть мониторит какой-нибудь файл в простейшем случае или обменивается с консольной по пайпу?


I>Нет тут, надо исходить и того, что такое как бы требование- надо чтобы было консольное приложене. На самом деле это библиотека и надо чтобы ее можно было использовать и в консольном приложении тоже. Все это под линукс, тут все горазло проще чем под виндой. То есть изначально нет разницы что это за приложение. Тут нет такого понятия как "подсистема" как в винде.


Раз библиотека — просто реализуешь нужные функции, и всё. А откуда они будут вызываться — проблема пользователя библиотеки
Re[9]: Создать окна в консольном приложении. Как?
От: удусекшл  
Дата: 15.11.21 08:46
Оценка:
Здравствуйте, imh0, Вы писали:

BFE>>>>Насколько я знаю процесс может либо не иметь консоли, либо иметь ровно одну консоль. Так что все окна вам придётся рисовать внутри одной и той же консоли.


I>>>Ну во первых консолей можно открыть сколько хочешь, и в винде и в линуксе....

BFE>>И для каждого придётся запустить отдельный процесс.

I>Да ладно...


Не ладно
В линупсах, скорее всего, как-то так же
Re[12]: Создать окна в консольном приложении. Как?
От: удусекшл  
Дата: 15.11.21 08:47
Оценка:
Здравствуйте, B0FEE664, Вы писали:


BFE>Елки-палки! Опять это секретное знание ускользнёт от меня. Ну намекните хотя бы, в какое из множества консольных окон будет направлен вывод printf?


Ну, если бы такое было бы возможно, то наверное printf выводил бы в ту консоль, к которой приаттачен STDOUT
Re[5]: Создать окна в консольном приложении. Как?
От: B0FEE664  
Дата: 15.11.21 08:48
Оценка:
Здравствуйте, fk0, Вы писали:

BFE>>Если он хочет несколько консольных окон в одном приложении с одним(!) запущенным процессом — то это не возможно.


fk0> С хера ли невозможно? Запускай 10 штук xterm'ов и каким-то образом передавай от них файл-дескрипторы, от slave-конца псевдотерминала себе в аппликацию. Через, например, некий мелкий процесс который тебе их, файл-дескрипторы, через сокет обратно вышлет, например. ...


Т.е. сторонний процесс всё равно обязателен.
И каждый день — без права на ошибку...
Re[6]: Создать окна в консольном приложении. Как?
От: imh0  
Дата: 15.11.21 08:54
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Т.е. сторонний процесс всё равно обязателен.


)) Нет, не обязателен!! ) Кончай уже офтопить. Где тут винда и консоли в форуме QT?
Как делать рассказывать не буду, и не проси. )
Re[9]: Создать окна в консольном приложении. Как?
От: B0FEE664  
Дата: 15.11.21 09:00
Оценка:
Здравствуйте, Skorodum, Вы писали:

BFE>>Проблемы могут быть связаны со скоростью: вывод в одно окно тормозит вывод во всех других окнах.

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

Или будет
Автор: A.J.
Дата: 24.06.21
. От задачи зависит.
И каждый день — без права на ошибку...
Re[7]: Создать окна в консольном приложении. Как?
От: B0FEE664  
Дата: 15.11.21 11:12
Оценка:
Здравствуйте, imh0, Вы писали:

BFE>>Т.е. сторонний процесс всё равно обязателен.

I>)) Нет, не обязателен!! )
Вы сами себе противоречите.

I>Кончай уже офтопить. Где тут винда и консоли в форуме QT?

Я что-то писал про винду? Винда или линукса, так или иначе придётся создавать отдельный процесс для ввода-вывода.
Что же касается офтопа, то вполне может быть, что вся тема к Qt отношения не имеет, так как для того, чтобы создать приложение, которое запускает несколько общающихся друг с другом процессов с консольными окнами можно сделать как с использованием Qt, так и без Qt.

I>Как делать рассказывать не буду, и не проси. )

Жаль.
И каждый день — без права на ошибку...
Re[10]: Создать окна в консольном приложении. Как?
От: Skorodum Россия  
Дата: 16.11.21 12:53
Оценка:
Здравствуйте, fk0, Вы писали:

S>>Установить обработчик на ctrl+c и спросить пользователья точно ли он хочет выйти

fk0> А если пользователь выходит по Ctrl-\ ? А если по Ctrl-Z и Ctrl-D, Ctrl-D ?
Так же установить обработчик, если это желаемое поведение

fk0>А если пользователь мышкой закрывает xterm в котором программа?

fk0>А если зашёл через ssh и тут интернет оборвался?
fk0>А если сисадмина обидели, он уволился и в кронтаб вставил kill -11 $RANDOM ?
Ничего не делать. Стандартное поведение в таких случаях — умереть. Чтобы поведение было нестандартным должны быть очень веские причины.
Re: Создать окна в консольном приложении. Как?
От: Vzhyk2  
Дата: 17.11.21 06:35
Оценка:
I>Есть простое консольное приложение.
I>Требуется в зависимости от каких-то событий, создавать окна.
Практически любая либа для гуйев тебе такую возможность предоставляет. Но если у тебя нет дисплея для окошек, то где эти окна ты будешь создавать?
Re[10]: Создать окна в консольном приложении. Как?
От: Skorodum Россия  
Дата: 06.12.21 13:38
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Или будет
Автор: A.J.
Дата: 24.06.21
.

Не воспроизводится
Попробовал в QtCreator:
  Картинка

Все летает на ноуте с интеловской картой

BFE>От задачи зависит.

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