LINUX.ORG.RU

На чем удобно делать GUI?

 


1

3

Ищу нечто, где просто и легко можно создавать GUI, с минимумом писанины кода (желательно, не трогая визуальные средства и всякие XML). Не важно под какую платформу (если даже оно под Amiga), не важно какого года, не важно какие требования к ресурсам или зависимостям. Особенно интересны средства, где можно сделать тысячу окошек с разными кисточками/палитрами (как в Гимпе), склеивать/разделять эти окошки в рантайме, при этом желательно не изводить пользователя тысячей нативных окон, как это когда-то делал Гимп.

Ответ на: комментарий от yyk
#The first button calls a procedure (a callback) that switches the 
#buttons name between Hello and Goodbye. The second button
#executes a command that destroys the window.

set text Hello
proc doIt {widget} {
    global text
    if {$text == "Hello"} {
        set text "Goodbye"
    } else {
        set text "Hello"
    }
    $widget configure -text $text
}

button .b1 -text "Hello" \
        -command "doIt .b1"
button .b2 -text "Quit" \
    -command "destroy ."

# Put them in the window in row order
grid .b1 -row 0 -column 0
grid .b2 -row 0 -column 1

В принципе, могло быть хуже. Не нравится: необходимость грида, да и в общем-то многословность. Но пока неплохо, гораздо проще Qt

ruzisufaka
() автор топика
Ответ на: комментарий от Norgat

Фотошоп у меня есть, как и более подходящие средства для рисования. Я же и фрилансер. А вот понимания, на чем делать 1000 окошек внутри приложения - нет.

ruzisufaka
() автор топика
Ответ на: комментарий от anonymous

SDL - это голая абстрация от железа, даже кнопку на нем не нарисуешь. Не говоря уже о 1000 окошках. Спасибо что напомнил, сейчас буду разбираться как задать стартовую позицию окна в нем

ruzisufaka
() автор топика
Ответ на: комментарий от anonymous

Сначала рисуем кнопочки, потом интерфейс, коннектим сигналы/слоты, а только потом пишем обработчик кнопочки, унаследовавшись от интерфейса, так? Я хотел бы потратить время на что-то такое, что позволит мне закончить проект хоть как-то, а уж потом думать о допиле. Покупать труд копипастеров, к сожалению, не могу - нет денег.

ruzisufaka
() автор топика
Ответ на: комментарий от ruzisufaka

Я хотел бы потратить время на что-то такое, что позволит мне закончить проект хоть как-то

и выглядеть твой гуй будет как говно.

anonymous
()
Ответ на: комментарий от futurama

Спасибо, просто не эксперт в нем, как раз ищу что-то.

ruzisufaka
() автор топика
Ответ на: комментарий от anonymous

и выглядеть твой гуй будет как говно.

Зато это можно будет продать, на полученные деньги нанять анонимусов, которые будут денно и ношно переписывать это на кутю и версии эдак к 5-й вообще перейдут на веб-интерфейс, а я буду где-то на Бали, подыхать от укуса мухи и заболевания тамошней пиздецомой, но это будет лучше, чем потратить остатки жизни на QML

ruzisufaka
() автор топика
Ответ на: комментарий от ruzisufaka

даже кнопку на нем не нарисуешь

Ты просто рисовать не умеешь.

anonymous
()
Ответ на: комментарий от splinter
// callback.cxx (example 2b)

#include <fltk/run.h>
#include <fltk/Window.h>
#include <fltk/Slider.h>
#include <fltk/Button.h>
#include <fltk/IntInput.h>
#include <stdlib.h>
using namespace fltk;

IntInput* intinput;

void copy_callback(Widget*, void* v) {
  Slider* slider = (Slider*)v;
  slider->value(intinput->ivalue());
}

void down_callback(Widget*, void* v) {
  Slider* slider = (Slider*)v;
  slider->value(slider->value()-1);
  intinput->value(slider->value());
}

void up_callback(Widget*, void* v) {
  Slider* slider = (Slider*)v;
  slider->value(slider->value()+1);
  intinput->value(slider->value());
}

void slider_callback(Widget* w, void*) {
  Slider* slider = (Slider*)w;
  intinput->value(slider->value());
}

void exit_callback(Widget *, void *) {
  exit(0);
}

int main(int argc, char ** argv) {
  Window window(320, 90);
  window.begin();
  IntInput intinput(10,10,100,20);
  ::intinput = &intinput;
  intinput.value(0.0);
  Button copy_button(110, 10, 100, 20, "copy to slider");
  Slider slider(10,35,300,20);
  slider.type(Slider::TICK_ABOVE);
  slider.clear_flag(LAYOUT_VERTICAL);
  slider.callback(slider_callback);
  copy_button.callback(copy_callback, &slider);
  slider.range(-10,10);
  slider.step(1);
  slider.value(0);
  Button down_button(50,60,50,20,"down");
  down_button.callback(down_callback, &slider);
  Button up_button(150,60,50,20,"up");
  up_button.callback(up_callback, &slider);
  Button exit_button(250,60,50,20,"exit");
  exit_button.callback(exit_callback);
  window.end();
  window.show(argc,argv);
  return run();
}

Выглядит приятно, не инопланетно как TK, умеет во множество окошек, но смущает задание координат (про редактор в курсе, но мне лень переключаться куда-то при написании кода), равно как и слишком подробное создание окна. Коллбеки же опять будут образовывать лесенку вызовов, если кнопок много - будет неприятно. Не нашел списков, куда бы кисточки свои засунуть можно было бы.

ruzisufaka
() автор топика
Ответ на: комментарий от ruzisufaka

остатки жизни на QML

Мне хватило одного вечера чтоб разобрать что к чему. Потом просто справочник по компонентам нужен и все.

anonymous
()
Ответ на: комментарий от ruzisufaka

Зато это можно будет продать

с говногуем-то ? ну если распильные деньги то наверно можно, но тогда чего заморачиваться - дельфи очевидно.

anonymous
()
Ответ на: комментарий от ruzisufaka

равно как и слишком подробное создание окна

это ж плюс, в начале в макрос под BASIC :-) и фигач если всё одинаково.

splinter ★★★★★
()
Ответ на: комментарий от anonymous

Денег нету, есть только я, моя гениальная идея и моё свободное время. Очевидно, что если это время использовать на глупости вроде рисования формочек, то проект будет закончен через большее количество человеколет, чем живет человек в среднем. Потому ищу простой и эффективный способ формошлепства без формошлепства (тем более, что мне надо 1000 формочек держать на экране одновременно)

ruzisufaka
() автор топика

желательно, не трогая визуальные средства и всякие XML

Это как раз и есть с мимнимумом кода, декларативное описание всегда мощнее императивного, а визуальное - вообще вершина прогресса

annulen ★★★★★
()
Ответ на: комментарий от annulen

Это как раз и есть с мимнимумом кода, декларативное описание всегда мощнее императивного, а визуальное - вообще вершина прогресса

Да, надо что-то поправить - сначала лезем в визуальный редактор, потом им сренькаем сгенерированный код, не забывая айдишники потом лезем в обработчики. В особых случаях код кнопки размазан в 3х и более местах, включая всякие локализации и тому подобное. Хочешь поменять кнопку - поменяй ВЕЗДЕ. Очень удобно, да.

ruzisufaka
() автор топика
Ответ на: комментарий от ruzisufaka

В gtk/glade не так. Просто меняешь xml`ку через gui и всё. Никакого «сгенерированного кода».

Обработчики вешаются прямо в glade. В коде ты только грузишь xml`ку и пишешь код обработчиков.

pawnhearts ★★★★★
()

Groovy SwingBuilder. Минимум кода ибо Groovy, удобненко интерфейсы генерить. Правда тормозит-с, ибо опять таки Groovy.

Deleted
()
Ответ на: комментарий от Deleted
...
            </p>
            <h2>header.one.
            <div style="border: 1px solid red; margin: 15px; text-align: left;">
                <object type="text/groovy"><![CDATA[
import net.miginfocom.swing.MigLayout
import net.miginfocom.layout.LC
import net.miginfocom.layout.AC
import net.miginfocom.layout.CC

/**
 * A script expected to run in SwingBuilder#build
 *
 * It demonstrates defining the layout using LC, AC objects.
 */
final LC layC = new LC().fill().wrap();
final AC colC = new AC().align("right", 0).fill(1, 3).grow(100, 1, 3).align("right", 2).gap("15", 1);
final AC rowC = new AC().index(6).gap("15!").align("top").grow(100, 8);

final def migLayout = new MigLayout( layC, colC, rowC )
panel(layout: migLayout) {
    label("Last Name")
...

1. Я конечно просил чего-то оригинального...

2. А это действительно то, что я искал?

ruzisufaka
() автор топика
Ответ на: комментарий от CARS

А можно пример создания окошка, кнопки в нем? Я пролистал 10 страниц туториала, но кода так и не увидел.

ruzisufaka
() автор топика
Ответ на: комментарий от ruzisufaka

Я так понимаю, в нем сначала надо создать форму, а без мышевозенья не обойтись?

Можно создать и из кода полностью, но я так не делал.

rezedent12 ☆☆☆
()
Ответ на: комментарий от ruzisufaka

А это действительно то, что я искал?

Да

минимумом писанины кода (желательно, не трогая визуальные средства и всякие XML). Не важно под какую платформу (если даже оно под Amiga), не важно какого года, не важно какие требования к ресурсам или зависимостям.

Под все подходит. Надо только немного расширить сознание до понимания Groovy. Будет минимум кода, можно переиспользовать все по максимуму.

Ты не тот пример нашел. Вот нормальный:

    import groovy.swing.SwingBuilder  
    import static javax.swing.JFrame.EXIT_ON_CLOSE  
    import static java.awt.BorderLayout.*  
      
    def swing = new SwingBuilder()  
    swing.edt {  
       frame( title: "File Viewer", pack: true, show: true,  
              defaultCloseOperation: EXIT_ON_CLOSE, id: "frame" ) {  
          borderLayout()  
          panel( constraints: NORTH ) {  
             borderLayout()  
             textField( id: "filename", constraints: CENTER )  
             button( "Load", constraints: EAST, actionPerformed: { evt ->  
                doOutside {  
                   def contents = new File(filename.text).text  
                   doLater { fileview.text = contents }  
                }  
             })  
          }  
          scrollPane( constraints: CENTER ) {  
             editorPane( id: "fileview", editable: false )  
          }  
       }  
    }  
      
    swing.doLater { frame.size = [480,320] }  
Deleted
()
Ответ на: комментарий от Deleted

Надо только немного расширить сознание до понимания Groovy.

Собственно, за расширением сознания я сюда и пришел. Пример шикарный. Пугает правда полное незнание Groovy и попытка его выучить несколько лет назад кончилась ничем, после жабки он какой-то странный. Вот к примеру, фигурные скобки у scrollPane - это что? Что такое doLater?

ruzisufaka
() автор топика
Ответ на: комментарий от ruzisufaka

Что такое doLater?

передача в doLater замыкания аналогична вызову SwingUtilities.invokeLater(Runnable r). Иначе говоря, все построение/обновление UI будет идти в отдельном потоке. Короче, почитай

фигурные скобки у scrollPane - это что?

Это замыкание. Таким образом ты здесь задаешь дочерний объект, в данном случае ты в ScrollPane добавляешь EditorPane.

Deleted
()
Ответ на: комментарий от Deleted

Таким образом ты здесь задаешь дочерний объект, в данном случае ты в ScrollPane добавляешь EditorPane.

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

будет идти в отдельном потоке

def contents = new File(filename.text).text  
doLater { fileview.text = contents }

Если создание окна в новом треде я еще понимаю, то вот такое...

ruzisufaka
() автор топика
Ответ на: комментарий от ruzisufaka

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

Правильно, это ж просто синтаксический сахар над джавовским Swing.

Если создание окна в новом треде я еще понимаю, то вот такое...

Тут файл читается и отображается в контроле, если ты будешь в UI-потоке это делать, то на больших файлах будет подвисать UI.

Deleted
()

(require 'вброс)

HTML же, ну!

ugoday ★★★★★
()
Ответ на: комментарий от ruzisufaka

Сначала рисуем кнопочки, потом интерфейс, коннектим сигналы/слоты, а только потом пишем обработчик кнопочки, унаследовавшись от интерфейса, так?

Ты перепутал С++/Qt c QML/Quick. На Quick кода будет не больше, чем в примере на Groovy.

Dendy ★★★★★
()

На коленке. У нас в фирме похоже так и делают. Пока работает.

Deleted
()

Что может быть проще:

import QtQuick 2.7
import QtQuick.Controls 1.5
import QtQuick.Dialogs 1.2

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    menuBar: MenuBar {
        Menu {
            title: qsTr("File")
            MenuItem {
                text: qsTr("&Open")
                onTriggered: console.log("Open action triggered");
            }
            MenuItem {
                text: qsTr("Exit")
                onTriggered: Qt.quit();
            }
        }
    }

    MainForm {
        anchors.fill: parent
        button1.onClicked: messageDialog.show(qsTr("Button 1 pressed"))
        button2.onClicked: messageDialog.show(qsTr("Button 2 pressed"))
    }

    MessageDialog {
        id: messageDialog
        title: qsTr("May I have your attention, please?")

        function show(caption) {
            messageDialog.text = caption;
            messageDialog.open();
        }
    }
}

?

EXL ★★★★★
()
Ответ на: комментарий от EXL

Увы, но в системную тему оно не очень умеет. Да и того же файлового диалога нету. А в Qt Quick Controls 2 так вообще выпили все темы.

RazrFalcon ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.