Size: a a a

2020 February 14

АП

Александр Петров in Qt
Alexander N
Есть ли вещь для отслеживания ивентов итд qt?
QEvent? И прочее прочие от него? А-ля QMouseEvent? Или не понял вопроса?
источник

АП

Александр Петров in Qt
Такой, кстати, вопрос: есть QDoubleSpinBox, необходимо реализовать его так, чтобы можно было устанавливать лишь числа из определенного диапазона, кратные некоемому числу. Это можно сделать через валидатор? И если да, то как? SetValidator у спин Эдита нет, но есть validate, который, вроде бы, в чем то похож..
источник

RL

Roman Levkovych𓅝 in Qt
что значит probe в gammaray? И как его поменять?
источник

W

WoodyFire in Qt
Всем доброго дня.
Помогите разобраться с системой расширений. В голове такая каша, что ниточки связать не могу.

Читаю книгу по Qt 5.10 Глава 42. В этой главе изначально идут динамические библиотеки, а потом система расширений.

С динамическими библиотеками вроде все понятно, но есть НО... Функции различные, ну к примеру там вычислить сумму двух слагаемых код накидать и с компилить в принципе я смогу и смогу подключить и воспользоваться этой функцией из библиотеки. Правда теоретически. Но разбирал я как то с человеком DLL и как их готовят и используют. Правда я могу лишь функции какие-нибудь накидать и использовать. Но этого еще никогда не делал.

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

В общем как я понял из 42 главы для написания расширений к своему приложению необходимо подготовить "интерфейс" (класс с виртуальными определениями методов) и идентифицировать "интерфейс" при помощи макроса Q_DECLARE_INTERFACE() это для MOC с целью генерации метаинформации, которая в дальнейшем будет использоваться объектом класса QPluginLoader при загрузке плагина.

Сам плагин его класс должен наследоваться от двух классов QObject и класс выше созданного интерфейса.

по мимо макроса Q_OBJECT в определении класса, необходимо применить еще пару макросов - это Q_INTERFASES(наименование интерфейса) - это макрос нужен я так понимаю даем имя создаваемому интерфейсу плагина.
Q_PLUGIN_METADATA(IID "com.mysoft.Application.NameInterface" FILE "nameinterface.json") - а здесь прописываем метаинформацию по интерфейсу.

Описал часть того, что вроде понял. А вот дальше для меня по большей части темный лес похоже.

В книге описан плагин который предназначен для работы с текстом. Ну это про, что я и говорил функцию суммы накидать и все такое. А вот с GUI как работать?
К примеру плагин загружен ядром приложения и предоставляет определенный функционал. Например появляется QDockWidget (здесь ну незнаю краткая сводка выездов взятая с БД) или там QToolBar (с привяской к пунктам меню) и пункты в меню (при нажатии на пункт меню выходит окно и там какой-нибудь функционал).

Вот примеры из книги.
Сам класс "Интерфейса"
#pragma once
class QString;
class QStringList;
// ======================================================================
class StringInterface {
public:
   virtual ~StringInterface() {}
   virtual QStringList operations() const = 0;
   virtual QString operation(const QString& strText,const QString& strOperation) = 0;
};

Q_DECLARE_INTERFACE(StringInterface,"com.mysoft.Application.StringInterface")



далее метод загрузки плагинов из указанной директории. То есть грузиться все, что является плагином. Там 2, 3, 10 плагинов и т.д.

void PluginsWindow::loadPlugins()
{
   QDir dir(QCoreApplication::applicationDirPath());
   #ifdef Q_OS_OSX
       dir.cdUp();
   #endif
   if (!dir.cd("plugins")) {
   QMessageBox::critical(0, "", "plugins directory does not exist");
   return;
   }

   foreach (QString strFileName, dir.entryList(QDir::Files)) {
       QPluginLoader loader(dir.absoluteFilePath(strFileName));
       addToMenu(qobject_cast<QObject*>(loader.instance()));
   }
}


Для меня тут впринципе вроде все понятно.

Дальше добавление пунктов в меню в зависимости от предоставляемых возможностей плагином.
void PluginsWindow::addToMenu(QObject* pobj)
{
   if (!pobj) {
       return;
   }
   
   StringInterface* pI = qobject_cast<StringInterface*>(pobj);
   
   if (pI) {
       QStringList lstOperations = pI->operations();
       foreach (QString str, lstOperations) {
           QAction* pact = new QAction(str, pobj);
           connect(pact, SIGNAL(triggered()), this, SLOT(slotStringOperation()));
           m_pmnuPlugins->addAction(pact);
       }
   }
}
источник

W

WoodyFire in Qt
Как я понимаю приведенные выше методы loadPlugins() & addToMenu(QObject* pobj) - это методы для размещения в моем ядре приложения.

Первый метод который просматривает папку, загружает файл, и отдает второму методу для добавления пунктов меню.
Второй метод получает указатель (INSTANCE) загруженного плагина. Согласно ранее определенного виртуального класса "интерфейса" вызывает метод operations() и получает возможности плагина. В данном случае получает набор строк для пунктов меню.


Получается, что таким образом, можно создать меню от плагина или пункты меню в окне главного окна или в системном трее?

Тут, ну допустим я понял.

Что пока не понятно что к чему. Получается класс интерфейса с виртуальными методами является болванкой и точкой входа для будущих плагинов нашего приложения. Определение этого интерфейса может быть и больше. Верно понимаю?

Так как мы определили болванку, то мы и назначаем метод который будет из нее вызываться первым для получения "точки входа". А кто будет писать плагин он должен использовать этот метод для первоначального взаимодействия с ядром приложения.

Получается, что вместо функции работы со строками можно определить метод создания какого-то QWidget или там пользовательского AppWidget и показа его на экране. Так?

Еще этот плагин будет работать в процессе ядра приложения. А возможно и нужно ли ему накинуть другой поток от процесса? Я в этой теме совсем пока плаваю. Но как я понимаю для паралельной работы нужен новый (отдельный поток) для данного GUI или плагина в целом.

Еще плагин загрузился в ядро, находится в одном процессе. Это значит что он использует одно адресное пространство с ядром приложения. Значит имеется возможность обмениваться какой-либо информацией или функциональностью. К примеру виджет из плагина обнаружив плагин по работе с БД обращается к плагину, получает соединение к БД и совершает запрос с последующим показом информации к примеру в QDockWidget . Верно?

Пока писал такое большое сообщение, меня посетила мысль, что у меня просто глаза боятся, так как такого еще никогда не делал. (

Нужно начать писать, а там уже будет поглядеть.
источник

VN

Vladislav Navrocky in Qt
WoodyFire
Как я понимаю приведенные выше методы loadPlugins() & addToMenu(QObject* pobj) - это методы для размещения в моем ядре приложения.

Первый метод который просматривает папку, загружает файл, и отдает второму методу для добавления пунктов меню.
Второй метод получает указатель (INSTANCE) загруженного плагина. Согласно ранее определенного виртуального класса "интерфейса" вызывает метод operations() и получает возможности плагина. В данном случае получает набор строк для пунктов меню.


Получается, что таким образом, можно создать меню от плагина или пункты меню в окне главного окна или в системном трее?

Тут, ну допустим я понял.

Что пока не понятно что к чему. Получается класс интерфейса с виртуальными методами является болванкой и точкой входа для будущих плагинов нашего приложения. Определение этого интерфейса может быть и больше. Верно понимаю?

Так как мы определили болванку, то мы и назначаем метод который будет из нее вызываться первым для получения "точки входа". А кто будет писать плагин он должен использовать этот метод для первоначального взаимодействия с ядром приложения.

Получается, что вместо функции работы со строками можно определить метод создания какого-то QWidget или там пользовательского AppWidget и показа его на экране. Так?

Еще этот плагин будет работать в процессе ядра приложения. А возможно и нужно ли ему накинуть другой поток от процесса? Я в этой теме совсем пока плаваю. Но как я понимаю для паралельной работы нужен новый (отдельный поток) для данного GUI или плагина в целом.

Еще плагин загрузился в ядро, находится в одном процессе. Это значит что он использует одно адресное пространство с ядром приложения. Значит имеется возможность обмениваться какой-либо информацией или функциональностью. К примеру виджет из плагина обнаружив плагин по работе с БД обращается к плагину, получает соединение к БД и совершает запрос с последующим показом информации к примеру в QDockWidget . Верно?

Пока писал такое большое сообщение, меня посетила мысль, что у меня просто глаза боятся, так как такого еще никогда не делал. (

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

W

WoodyFire in Qt
Vladislav Navrocky
Тебе нужно резиновую уточку купить и ей всё это рассказывать
Она у меня есть, вот только молчит она и на мои вопросы не отвечает. Может Вы ответите на вопросы в моем контексте?
источник

VN

Vladislav Navrocky in Qt
WoodyFire
Она у меня есть, вот только молчит она и на мои вопросы не отвечает. Может Вы ответите на вопросы в моем контексте?
Я не смог осилить столько текста 😕
источник

W

WoodyFire in Qt
Vladislav Navrocky
Я не смог осилить столько текста 😕
Жаль
источник

VN

Vladislav Navrocky in Qt
В целом надо понимать ООП, интерфейсы и как грузится SO/DLL, тогда все становится понятно
источник

VN

Vladislav Navrocky in Qt
Есть точка входа. Qt когда грузит so/dll обращается к этой точке входа и получает объект-описатель плагина. Далее уже сам делаешь абстракции как хочешь
источник

W

WoodyFire in Qt
Vladislav Navrocky
Есть точка входа. Qt когда грузит so/dll обращается к этой точке входа и получает объект-описатель плагина. Далее уже сам делаешь абстракции как хочешь
Вот на один вопрос ответили!
источник

W

WoodyFire in Qt
Вот только кто такой объект описатель? "Интерфейс"? Если по книге
источник

VN

Vladislav Navrocky in Qt
WoodyFire
Вот только кто такой объект описатель? "Интерфейс"? Если по книге
class MyPlugin: public QObject, public MyPluginInterface
источник

W

WoodyFire in Qt
Vladislav Navrocky
class MyPlugin: public QObject, public MyPluginInterface
Ну это я уже все вычитал.
источник

W

WoodyFire in Qt
Мне дальше не совсем все понятно.
источник

VN

Vladislav Navrocky in Qt
WoodyFire
Ну это я уже все вычитал.
Ну и всё, дальше сам придумываешь методы.
источник

W

WoodyFire in Qt
Vladislav Navrocky
Ну и всё, дальше сам придумываешь методы.
С простыми методами как показано в книге думаю проблем у меня не возникнет. А Вы говорите примерно про это, как я понимаю.
Мне хотелось бы реализовать, что то подобие как к примеру в LibreOffice. Где Calc, Writer и т.д. являются как я понял типа плагинами загруженными ядром LibreOffice. Конечно я может и ерунду несу. Но я увидел примерно такую картину.
источник

W

WoodyFire in Qt
Там кстати модель UNO примерно напоминает схему подобную приведённую в книге по Qt. "com.soft.application.interfaces"
источник

A

Alex in Qt
У меня в сегенеренном qmake проекте для Visual Studio 2019 откуда-то взялся флаг компилятора /FC, это недавно появилось. Как можно его убрать?
источник