Russian Qt Forum
Ноябрь 24, 2024, 01:25 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 2 [3]   Вниз
  Печать  
Автор Тема: Генерация кода из ui.  (Прочитано 21689 раз)
kuzulis
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2812


Просмотр профиля
« Ответ #30 : Декабрь 19, 2012, 15:51 »

Цитировать
Понятно?
Проще тебе написать мааленький примерчик, чем говорить, тогда уж точно все станет понятно.  Улыбающийся
Записан

ArchLinux x86_64 / Win10 64 bit
Bepec
Гость
« Ответ #31 : Декабрь 19, 2012, 15:53 »

Цитировать
Re: Генерация кода из ui.
« Ответ #20 : Сегодня в 12:40 »
К этому сообщению приложен скрипт. Времени его искать снова нет. Пользуйтесь.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #32 : Декабрь 19, 2012, 18:38 »

Проще тебе написать мааленький примерчик, чем говорить, тогда уж точно все станет понятно.  Улыбающийся
Да пожалуйста:
Код
C++ (Qt)
#include <QApplication>
#include <QMainWindow>
#include <QMenuBar>
#include <QStatusBar>
#include <QMenu>
#include <QUiLoader>
#include <QFile>
#include <QMetaObject>
#include <QDebug>
 
class Actions : public QObject
{
Q_OBJECT
public:
Actions( QMainWindow* mw )
: QObject( mw )
, sb_( mw->statusBar() )
{
foreach( QMenu* m, mw->menuBar()->findChildren< QMenu* >() )
QObject::connect( m, SIGNAL( triggered(QAction*) ),
this, SLOT( invokeAction(QAction*) ) );
}
 
private:
QStatusBar* sb_;
 
private Q_SLOTS:
void invokeAction( QAction* a )
{
QMenu* menu = qobject_cast< QMenu* >( sender() );
 
if( !menu->actions().contains( a ) ) // ignore submenu actions
return;
 
QString func_name = sender()->objectName();
if( func_name.startsWith( "menu" ) )
func_name.remove( 0, 4 );
func_name.replace( 0, 1, func_name.at( 0 ).toLower() );
QString action_name = a->objectName();
if( action_name.startsWith( "action" ) )
action_name.remove( 0, 6 );
action_name.replace( 0, 1, action_name.at( 0 ).toUpper() );
func_name += action_name;
 
if( a->isCheckable() )
QMetaObject::invokeMethod( this, func_name.toLatin1().constData(),
Qt::QueuedConnection, Q_ARG( bool, a->isChecked() ) );
else
QMetaObject::invokeMethod( this, func_name.toLatin1().constData(),
Qt::QueuedConnection );
}
 
public Q_SLOTS:
void fileNew()
{
sb_->showMessage( "fileNew() invoked..." );
}
void fileClose()
{
sb_->showMessage( "fileClose() invoked..." );
}
void fileQuit()
{
qApp->exit( 0 );
}
 
void openFile()
{
sb_->showMessage( "openFile() invoked..." );
}
void openUrl()
{
sb_->showMessage( "openUrl() invoked..." );
}
 
void viewNormal( bool set )
{
sb_->showMessage( QString( "viewNormal(%1) invoked..." ).arg( set ) );
}
void viewFullScreen( bool set )
{
sb_->showMessage( QString( "viewFullScreen(%1) invoked..." ).arg( set ) );
}
};
 
int main( int argc, char* argv[] )
{
QApplication a( argc, argv );
QFile f( "mw.ui" );
QUiLoader loader;
 
QMainWindow* mw = qobject_cast< QMainWindow* >( loader.load( &f ) );
if( !mw )
{
qDebug() << "Can't load " << f.fileName();
return 1;
}
 
Actions actions( mw );
 
mw->show();
 
return a.exec();
}
 

Подгружаемый mw.ui
Код
XML
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
 <property name="geometry">
  <rect>
   <x>0</x>
   <y>0</y>
   <width>800</width>
   <height>600</height>
  </rect>
 </property>
 <property name="windowTitle">
  <string>MainWindow</string>
 </property>
 <widget class="QWidget" name="centralwidget"/>
 <widget class="QMenuBar" name="menubar">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>26</height>
   </rect>
  </property>
  <widget class="QMenu" name="menuFile">
   <property name="title">
    <string>File</string>
   </property>
   <widget class="QMenu" name="menuOpen">
    <property name="title">
     <string>Open</string>
    </property>
    <addaction name="actionFile"/>
    <addaction name="actionUrl"/>
   </widget>
   <addaction name="actionNew"/>
   <addaction name="menuOpen"/>
   <addaction name="actionSave"/>
   <addaction name="actionSave_As"/>
   <addaction name="separator"/>
   <addaction name="actionClose"/>
   <addaction name="actionQuit"/>
  </widget>
  <widget class="QMenu" name="menuEdit">
   <property name="title">
    <string>Edit</string>
   </property>
   <addaction name="actionCut"/>
   <addaction name="actionCopy"/>
   <addaction name="actionPaste"/>
  </widget>
  <widget class="QMenu" name="menuView">
   <property name="title">
    <string>View</string>
   </property>
   <addaction name="actionNormal"/>
   <addaction name="actionFullScreen"/>
  </widget>
  <addaction name="menuFile"/>
  <addaction name="menuEdit"/>
  <addaction name="menuView"/>
 </widget>
 <widget class="QStatusBar" name="statusbar"/>
 <action name="actionClose">
  <property name="text">
   <string>Close</string>
  </property>
 </action>
 <action name="actionFile">
  <property name="text">
   <string>File</string>
  </property>
 </action>
 <action name="actionUrl">
  <property name="text">
   <string>Url</string>
  </property>
 </action>
 <action name="actionQuit">
  <property name="text">
   <string>Quit</string>
  </property>
 </action>
 <action name="actionNew">
  <property name="text">
   <string>New</string>
  </property>
 </action>
 <action name="actionSave">
  <property name="text">
   <string>Save</string>
  </property>
 </action>
 <action name="actionSave_As">
  <property name="text">
   <string>Save As...</string>
  </property>
 </action>
 <action name="actionCut">
  <property name="text">
   <string>Cut</string>
  </property>
 </action>
 <action name="actionCopy">
  <property name="text">
   <string>Copy</string>
  </property>
 </action>
 <action name="actionPaste">
  <property name="text">
   <string>Paste</string>
  </property>
 </action>
 <action name="actionNormal">
  <property name="checkable">
   <bool>true</bool>
  </property>
  <property name="text">
   <string>Normal</string>
  </property>
 </action>
 <action name="actionFullScreen">
  <property name="checkable">
   <bool>true</bool>
  </property>
  <property name="text">
   <string>Full Screen</string>
  </property>
 </action>
</widget>
<resources/>
<connections/>
</ui>
 
Записан

Qt 5.11/4.8.7 (X11/Win)
Bepec
Гость
« Ответ #33 : Декабрь 19, 2012, 20:06 »

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

В вашем идёт чтение ui (вы рассчитываете, что все ui будут лежать в пределах досягаемости ручек пользователя?), дополнительный класс - менеджер (прекрасно (не ирония, я о таком подходе не подумал), см. PPS), двойной вызов сигналов ( не критично ), связывание в конструкторе, невнятные (от моего незнания) манипуляции в main.

Ваш пример можно доработать, ища не "все Qmenu", а используя только QMenuBar, как я уже писал, если верить ассистенту.

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

Мой подход имеет же прост, основан на стандартном связывании и как раз, по моему мнению, подходит для разработки форм средней сложности средними программистами.

PS снимаю перед вами шляпу - с помощью QUiLoader можно запепенить нормальную утилитку. Незнал, незнал.

PPS ваш подход прекрасен для запутанных проектов. Думаю, чуть подправив, можно свести все Action'ы в этот класс менеджер. Вот только в большинстве случаев меню виджета должно выполнять с ним какие то действия. У вас же получается отвязка от самих виджетов и необходимость дополнительной обвязки в каждом из MainWindow и как следствие нарушение инкапсуляции.




 
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #34 : Декабрь 19, 2012, 20:57 »

Вот уж не думал, что динамическая подгрузка *.ui будет так неоднозначно воспринята, тем более что это был всего-навсего пример.
В любом случае, мое дело предложить - твое отказаться.
Записан

Qt 5.11/4.8.7 (X11/Win)
Bepec
Гость
« Ответ #35 : Декабрь 19, 2012, 21:02 »

Ну почему же - нормально. Но в любом случае Веселый Необходимо делать эти слоты вручную. А это как раз тупая моторика. Не требующий ума монотонный набор одинаковых функций и прочего Улыбающийся
Записан
panAlexey
Гипер активный житель
*****
Offline Offline

Сообщений: 864

Акцио ЗАРПЛАТА!!!!! :(


Просмотр профиля
« Ответ #36 : Декабрь 20, 2012, 11:18 »

Можно еще один способ использовать:
1. Завести болванку под систему, которая реализует "общие" системные пункты, такие как обработка распространенного типа файлов - тесктовых, хтмл, или что там вашей софтине требуется, печать, вызов хелпа, управление окнами и т.д. и т.п.
2. Болванку под построение меняющихся интерфейсов. Т.е. туда, куда формы добавляются. Тут уже куча методов, от испоьзования уилоадеров до использования словаря метаданных.
Я именно так и сделал.
Записан

Win Xp SP-2, Qt4.3.4/MinGW. http://trdm.1gb.ru/
panAlexey
Гипер активный житель
*****
Offline Offline

Сообщений: 864

Акцио ЗАРПЛАТА!!!!! :(


Просмотр профиля
« Ответ #37 : Декабрь 20, 2012, 11:22 »

Ну почему же - нормально. Но в любом случае Веселый Необходимо делать эти слоты вручную. А это как раз тупая моторика. Не требующий ума монотонный набор одинаковых функций и прочего Улыбающийся
Если формам не нужны параметры, то я бы сделал мета-словарь, где перечислил путь к меню, имя файла формы и по ним создавал меню и связывал их с одним слотом мэпером. Можно и в QAction засунуть имя файла формы.
Записан

Win Xp SP-2, Qt4.3.4/MinGW. http://trdm.1gb.ru/
Bepec
Гость
« Ответ #38 : Декабрь 20, 2012, 11:37 »

panAlexey, разъясните мне пожалуйста концепцию болванки, а то чего й то не понимаю.

Просто в случае с словарём и прочими методами связь "пункта" и слота неочевидна и требуется обвязка. Повторюсь - для средних проектов.

PS мне просто обвязки очень ненравятся. Ибо я то разберусь, а кому другому надо будет изменить/добавить, то ему придётся разбираться в обвязке и необходимом количестве условий для её выполнения.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #39 : Декабрь 20, 2012, 12:01 »

Ваш пример можно доработать, ища не "все Qmenu", а используя только QMenuBar, как я уже писал, если верить ассистенту.
Дело в том, что если завязываться на QMenuBar::triggered( QAction* action ), то нам никак не узнать в каком именно меню выбрали пункт Грустный
Записан

Qt 5.11/4.8.7 (X11/Win)
Bepec
Гость
« Ответ #40 : Декабрь 20, 2012, 12:10 »

Почему?
Псевдокод
Код:
QMenu * menu = action.menu();
if (menu != myMenuBar)
    // че то тут.
Если добавить рекурсию, возможно получить все Menu. Или я неправ и при добавлении подменю в меню, он не становится его родителем? Незнаю.
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #41 : Декабрь 20, 2012, 12:13 »

Неправ по всем параметрам.
Неужто ты думаешь, я не проверил все варианты перед тем как утверждать)
Записан

Qt 5.11/4.8.7 (X11/Win)
panAlexey
Гипер активный житель
*****
Offline Offline

Сообщений: 864

Акцио ЗАРПЛАТА!!!!! :(


Просмотр профиля
« Ответ #42 : Декабрь 20, 2012, 17:49 »

panAlexey, разъясните мне пожалуйста концепцию болванки, а то чего й то не понимаю.
Да то же самое, что и наследование в ООП.
Есть класс который может многое и многое делает, ты берешь его за основу и добавляешь свои функции.
Записан

Win Xp SP-2, Qt4.3.4/MinGW. http://trdm.1gb.ru/
Bepec
Гость
« Ответ #43 : Декабрь 20, 2012, 18:16 »

Не, болванки в этом случае не катят Улыбающийся Слишком разный набор функций. Всё вместе собрать - получится крошево Веселый
Записан
Страниц: 1 2 [3]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.107 секунд. Запросов: 23.