Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: niXman от Декабрь 02, 2009, 18:26



Название: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: niXman от Декабрь 02, 2009, 18:26
Хай.

Есть реальная необходимость строить ГУЙ из некоего скрипта/шаблона/правила.

Т.е. есть код. Написан руками. Т.е. объекты - сигналы/слоты. Нужно часто менять внешний вид ГУИ. Постоянно редактировать формы дизайнером не дело, т.к. нужно перекомпилировать программу.

Я вижу решение этой задачи весьма простым(если чего-то не упустил. что возможно). Разработать синтаксис файла-дизайна, парсер, билдер.

пример скрипта:
Код
XML
form.button1(pos, xsize, ysize, other_attributes...)[signal_name, receiver, slot_name]
 

так же есть класс:
Код
C++ (Qt)
class Main: public QDialog {
  Q_OBJECT
public:
  ...
public slots:
  void slot_name();
};
 

пример использования.
Код
C++ (Qt)
int main(...) {
  ...
  Main* m = new Main;
  parser* p = new parser("filename");
  ...
}
 

принцип работы парсера/билдера:
1. классы, к которым парсер будет коннектить сигналы/слоты, должны быть созданы раньше него.
2. в скрипте, поле "receiver", содержит реальное имя класса.
3. в скрипте, поле "slot_name", содержит реальное имя слота декларированного в классе "receiver".

как-то так ;)

Есть ли что-то подобное уже написанное?

Если нет, буду писать.
Интересует, что я не учел? Какие "подводные камни" могут встретится? И вообще мнение компетентных в этом вопросе людей.

Всем спасибо.


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: MoPDoBoPoT от Декабрь 02, 2009, 18:45
Постоянно редактировать формы дизайнером не дело, т.к. нужно перекомпилировать программу.
Неа, не обязательно компилить  :)
ссылка (http://doc.crossplatform.ru/qt/4.5.0/quiloader.html)


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: Igors от Декабрь 02, 2009, 18:58
Многое зависит от того "кто и как будет этим пользоваться" и что значит "менять внешний вид UI"? Возникают ли новые параметры динамически? Если нет (или "почти нет"), то гораздо проще подсовывать разнообразные UI через QFormBuilder::load (введя какие-то соглашения по именам объектов).

У меня была такая задача: есть произвольная формула (вводимая пользователем), нужно ее "обсчитать" (детали не важны). Формула может иметь с десяток разнообразных параметров/коэффициентов которые нужно отобразить в UI и которые пользователь может менять. Я крутил с текстовыми ini файлами, примерно так:
Цитировать
[param]
name = Velocity;  // UI name
type = double;
min = 0;
max = 100;
UI = slider;          // UI control
...
 
Несмотря на простоту, писать пришлось довольно много :)


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: niXman от Декабрь 02, 2009, 19:08
Цитировать
Возникают ли новые параметры динамически?
Да. Но только визуальные.

Про предложения: все понятно, кроме одного, как быть с сигналами-слотами. В обоих предложенных вариантах, не нашел ничего про это.


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: Igors от Декабрь 02, 2009, 19:18
Цитировать
Возникают ли новые параметры динамически?
Да. Но только визуальные.
Не понимаю как это :) То есть контролы которые не влияют на результат?

Про предложения: все понятно, кроме одного, как быть с сигналами-слотами. В обоих предложенных вариантах, не нашел ничего про это.
В дизайнере простые слот/сигналы задать не проблема. Или, используя какие-то соглашения по именам объектов (это неизбежно), связать после загрузки/создания.


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: break от Декабрь 02, 2009, 19:24
QtScript позволяет использовать все QObject-ы значит и QWidget -в нем можно создавать - синтаксис почти не поменяется...


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: niXman от Декабрь 02, 2009, 19:26
Цитировать
То есть контролы которые не влияют на результат?
Набор контролов(в лучшем случае) меняться не будет. Меняться будет положение, размер, лэйоут, кэпшн, и т.д...


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: niXman от Декабрь 02, 2009, 19:30
Цитировать
QtScript позволяет использовать все QObject-ы значит и QWidget -в нем можно создавать - синтаксис почти не поменяется...
никогда не использовал. попробую разобраться.


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: Авварон от Декабрь 02, 2009, 22:59
связка qtScript + QUILoader. пример - калькулятор в qtdemo


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: SASA от Декабрь 03, 2009, 13:14
Где-то в блогах тролей видел интересную статейку. Там говорилось как можно создавать классы Qt прямо в скрипте.
Например:
Код:
p = new QLabel
Для решения задачи можно герить скрипт, а потом его выполнить.

QScript - мощная штука, если научиться переносить объекты С++ в скрипт.


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: break от Декабрь 03, 2009, 13:53
Цитировать
Там говорилось как можно создавать классы Qt прямо в скрипте.
Да прям в документации и говорится


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: ax от Декабрь 03, 2009, 17:07
посмотри на Qt Script Generator

(http://qt.gitorious.org/qt-labs/qtscriptgenerator (http://(http://qt.gitorious.org/qt-labs/qtscriptgenerator)

делает практически все qt классы доступными в QtScript.
тамже есть примеры использования.



Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: lit-uriy от Декабрь 03, 2009, 17:17
Есть такой проект Declarative UI у тролей, QML  и т.п., про них надо читать


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: Lestat от Декабрь 04, 2009, 21:16
Я для этих задач влепил в С++ код интерпретатор питона.
Рассчитывал связать PyQt со своей прогой, но не получилось, т.к. разные механизмы встраивания питона и обертки PyQt использовались.
Вот жду когда замутят PySide под винду... она вроде на Boost.Python, я как раз его юзал для заворачивания своих объектов.


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: spirits25 от Январь 11, 2012, 17:08
Затрагивая старое. Проблема вот в чём, есть много кнопок (создаются динамически), вызывающих один слот. Как определить какая из них вызвала его? как при коннекте связать с кнопкой какой-то парамерт (строку). для каждой кнопки слот создавать не вариант, так как всё динамически делается. Может в connect можно параметр как-то добавить?
ЗЫ пишу на pyside.


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: kambala от Январь 11, 2012, 18:00
есть метод sender() - он возвращает объект, который спровоцировал вызов слота. в твоём случае будет возвращать кнопку.


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: popper от Январь 11, 2012, 19:32
А еще есть QSignalMapper


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: thechicho от Январь 11, 2012, 21:05
объясни, зачем тебе узнавать какая кнопка вызывает слот и покажи как у тебя ща коннект сделан и какие данные тебе нужны


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: iroln от Январь 11, 2012, 23:27
http://qt.osdn.org.ua/signalmapper.html


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: spirits25 от Январь 12, 2012, 15:58
Спасибо всем, сделал так

Код:
class ButtonMap (QtGui.QPushButton):
    name = ""
    def __init__ (self, name, parent=None):
        self.name = name
        super(ButtonMap, self).__init__(s, parent)
        self.clicked.connect(self.buttonclick)
       
    but_click = QtCore.Signal(str)
    def buttonclick(self):
        self.but_click.emit(self.name)
ниже
Код:
        for num in range (0, len(results)):
            Button = ButtonMap(button_text)
            Button.but_click.connect(self.onActivated)
           
            self.button_list.append(Button)
            self.layout.addWidget(self.button_list[num])


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: kambala от Январь 12, 2012, 16:49
и ради этого надо было создавать новый класс?.. через sender() это делается без всяких новых классов - просто приводишь его к типу кнопки с помощью qobject_cast и считываешь её текст.


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: spirits25 от Январь 13, 2012, 10:03
и ради этого надо было создавать новый класс?.. через sender() это делается без всяких новых классов - просто приводишь его к типу кнопки с помощью qobject_cast и считываешь её текст.
Действительно проще, только немного не так, я ведь про PySide
Код:
    def onActivated(self):
        method_name = self.sender().text()
и всё=)


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: iroln от Январь 13, 2012, 10:09
Лучше использовать QSignalMapper - это с точки зрения ОО проектирования правильнее и красивее.
Тут всё по-русски написано http://qt.osdn.org.ua/signalmapper.html :)


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: spirits25 от Январь 13, 2012, 10:28
ещё вопрос, как приконнектиться к сигналу изменения размеров QtGui.QMainWindow?


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: iroln от Январь 13, 2012, 10:33
за это отвечает событие resizeEvent

В классе виджета надо определить метод resizeEvent и в нём обрабатывать событие измерения размеров окна.

Код
Python
class Window(QtGui.QMainWindow):
   def resizeEvent(self, event):
       # Тут что-то делаем при изменении размеров окна
 


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: spirits25 от Январь 16, 2012, 15:48
за это отвечает событие resizeEvent

В классе виджета надо определить метод resizeEvent и в нём обрабатывать событие измерения размеров окна.

Код
Python
class Window(QtGui.QMainWindow):
   def resizeEvent(self, event):
       # Тут что-то делаем при изменении размеров окна
 
спасибо, это просто запамятовал=)
А вот в другом встал.
Необходимо по нажатии кнопки выполнять большую функцию (точнее метод), которая изменяет gui, но беда в том, что пока всё действие кнопки не закончится, gui не меняется, а в самом конце выдаётся последний результат.

Что тут посоветуете? пробывал QThread (вылетает, пишет что поток из другого потока не сделать)
Код:
QObject: Cannot create children for a parent that is in a different thread.
(Parent is Oxygen::ScrollBarEngine(0x2444c70), parent's thread is QThread(0x157bc50), current thread is MyThread(0x31b7a80)
QObject::setParent: Cannot set parent, new parent is in a different thread
QObject::setParent: Cannot set parent, new parent is in a different thread
Ошибка сегментирования
и пробовал emit. Не помогло.


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: popper от Январь 16, 2012, 16:05
Попробуй QCoreApplication::flush ()


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: spirits25 от Январь 16, 2012, 16:22
Попробуй QCoreApplication::flush ()
Спасибо, попробовал - не помогло...
Код:
        QtCore.QCoreApplication.flush()
        self.ClientObj.app.flush()
и отдельно и как метод моего Application, никак не помогло.

QtGui.QApplication.flush() - тоже нет.
Сначала всё выполняется, потом обновляется виджет.


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: iroln от Январь 16, 2012, 23:32
А QApplication::processEvents?
Надо вызывать в той функции, которая что-то долго делает, но там должен быть цикл, иначе смысла нет.


Название: Re: Скриптовый динамический ГУИ билдер. Есть такой?
Отправлено: spirits25 от Январь 17, 2012, 08:47
А QApplication::processEvents?
Надо вызывать в той функции, которая что-то долго делает, но там должен быть цикл, иначе смысла нет.
Спасибо, помогло.
Если кому надо, вот нашёл про QApplication::processEvents http://www.opennet.ru/docs/RUS/qt3_prog/x4064.html (http://www.opennet.ru/docs/RUS/qt3_prog/x4064.html) там qt3, но разницы не вижу=)