LINUX.ORG.RU

Что плохого в сигнало-слотах?


0

0

Читаю "QT Профессиональное программирование на C++" Шлее. Там так вкусно рассказывается про сигнало-слоты, что непонятно как вообще все без них обходятся. Однако обходятся. И вроде бы не любят. В связи с этим два вопроса: собственно сабж и как обходятся без сигнало-слотов в других гуях (в том же gtk например)?

★★★★★

Ответ на: комментарий от jtootf

> у тебя от уровня ЧСВ позвоночник не прогибается?

Эпизодически. Нормальные в Qt сигналы, короче. Как пацан пацану тебе говорю.

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

Ну, все просто.

Есть понятие "блок прослушивания" - listener. Это объект класса, реализующего специальный интерфейс. Причем интерфейс выбирается в зависимости от события, которые мы хотим отлавливать. Есть классы, которые способны регистрировать в себе такие вот блоки прослушивания и сообщать им о некоторых событиях. Например JButton. Он имеет метод addActionListener(ActionListener actionListener).

Соответственно ActionListener - это интерфейс, в котором определен метод actionPerformed(ActionEvent ae). При нажатии на кнопку будет вызываться этот метод.

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

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

Я понятия не имею о Gtk+, Tcl/tk (или о чем ты там говорил?) - интересно было бы посмотреть так ли там все сладко, как ты пишешь.

Идет?

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

http://letoverlambda.com/back-cover.png

или что делать, если интерфейс был выбран неверно?

>Есть классы, которые способны регистрировать в себе такие вот блоки прослушивания и сообщать им о некоторых событиях

вот это - вполне понятно, особенно если на соединения таких вот блоков можно повесить некоторую управляющую логику

>Это объект класса, реализующего специальный интерфейс

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

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

я только за. только ты ТЗ как-нибудь уточни, что ли:

>одинаковые его обработчики, находящиеся в 10 различных потоках

>Задача обработчика - узнать источник сигнала и что-нибудь с ним сделать

т.е. все десять обработчиков должны сделать одно и то же? причём одновременно? это будет очень показательно, да :)

>в 10 различных потоках

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

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

> то есть я понимаю, что в Java всё есть класс, но тут-то он зачем?
Сам по себе класс тут немного вторичен, он часто вообще анонимный. Важно - это интерфейс. Контракт на обработку некоторой группы логически связанных сигналов. А класс только реализует этот контракт.

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

>Контракт на обработку некоторой группы логически связанных сигналов

а если в группе один сигнал? или один сигнал логически принадлежит нескольким группам?

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

> т.е. все десять обработчиков должны сделать одно и то же?

Пусть так, по сути важен лишь факт определения обработчиком источника сигнала.

> можно заменить на "параллельно выполняющихся"...?

Не вижу особой разницы, обработчики должны выполниться в различных, уже существующих до возникновения события потоках.

P.S. Не нужно воспринимать это как очередной замер e-пинусов - мне действительно интересно каким образом решаются подобные задачи в других языках/фреймворках, а также, но в меньшей степени - насколько хорошо это будет выглядеть в виде кода.

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

> а если в группе один сигнал?
Бывает и так. Интерфейс с одной функцией.

> или один сигнал логически принадлежит нескольким группам?

interface foo extends bar; interface blah extends foo;

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

>interface foo extends bar; interface blah extends foo;

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

или в этом примере bar - это и есть упоминавшийся выше интерфейс с одним методом?

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

>Пусть так, по сути важен лишь факт определения обработчиком источника сигнала.

загадочно, ну да ладно

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

понимаешь ли, не во всех event-driven языках есть явное понятие потока. поток - это всё-таки очень низкоуровневая сущность. именно потому я и переспросил

>мне действительно интересно каким образом решаются подобные задачи в других языках

что ж, посмотрим

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

> А для чего это может быть нужно? > Ну в этом то вообще нет ничего плохого. Это вроде за ради инкапсуляции.

Рассмотрим пример: есть текстовое поле, есть действия которые должны изменять шрифт текста в этом поле. В QWidget есть функция setFont(QFont) она не является слотом и её невозможно вызывать по сигналу QAction::triggered() (нет возможности задания дополнительных аргументов). Инкапсуляция не нарушается если можно было делать как в gtkmm: использовать произвольный функциональный объект для обработки сигнала. А система сигналов/слотов Qt приводит к написанию однострочных слотов. Добавление таких однострочных слотов ведёт к правке соотвествующего загловочного файла, что в свою очередь ведёт к перекомпиляции всех файлов, которые его включают.

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

> понимаешь ли, не во всех event-driven языках...

Возможность использовать потоки в Tcl/Tk, модели сообщений которого остается завидовать Qt, насколько я знаю, есть.

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

> если это совсем разные группы, просто имеющие один общий сигнал?
Так бывает нечасто. Скорее всего, если сигнал общий - что-то у групп общее есть. Ну или да, этот сигнал - отдельный интерфейс.

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

>Возможность использовать потоки в Tcl/Tk, модели сообщений которого остается завидовать Qt, насколько я знаю, есть.

да, потоки есть. просто кто-то из нас, похоже, не до конца понимает их реального назначения (с)

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

> да, потоки есть. просто кто-то из нас, похоже, не до конца понимает их реального назначения (с)

А что в Tcl/Tk понятие "поток" таит в себе какой-то секрет? Там этим словом называют не последовательность инструкций, выполняющихся параллельно основному процессу? Я не в курсе, просвети.

P.S. Что там с кодом? Не терпится взглянуть.

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

Конечно не понял, этот товарисч утверждает что статическая типизация - говно. Но когда его поделие выкинут из-за тормозов, а его уволят, то ему останется лишь доказывать что все неправы. А так, да без статической типизации удобнее писать, можно лепить извраты.

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

>Там этим словом называют не последовательность инструкций, выполняющихся параллельно основному процессу?

тебе термины Reactor/Proactor о чём-нибудь говорят? или ты до сих пор считаешь, что асинхронное выполнение можно реализовать исключительно с помощью процессов/потоков?

до тех пор, пока в массе своей ПК было однопроцессорными, существенной пользы от использования потоков вообще не было. были в основном проблемы. с точки зрения твоего C++-центричного мира советую почитать на этот счёт работы авторов ACE (Шмидта в частности). непосредственно к Tc/Tk это никакого отношения не имеет, просто элементарная компьютерная грамотность :)

>P.S. Что там с кодом? Не терпится взглянуть.

нетерпение - это плохо!

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

>этот товарисч утверждает что статическая типизация - говно

белка, иди в толксы. там тебя покормят

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

package require Thread

wm geometry . 200x100+0-0
wm resizable . 0 0

ttk::setTheme clam

set b [button .b -width 10 -height 10 -text "Push Me"]
place $b -in . -relwidth 1 -relheight 1

set mainID [thread::id]

proc a {w} {
   $w configure -text "$w"
}

set threads []

for {set x 0} {$x < 10} {incr x} {
   lappend threads [thread::create {
               proc print {id w} {
                  thread::send -async $id [list ::a [list $w]]
               }
            thread::wait
            }]
}

foreach th $threads {
   bind $b <ButtonRelease-1> { thread::send -async $th [list print $::mainID [list %W]] }
}

vwait forever

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

Вопрос был про потоки в Tcl/Tk, суть которых, как ты выразился, я не до конца понимаю. Чем был спровоцирован такой внезапный и неуместный урок истории/теории программирования осталось неясным. На ACE у меня как минимум один проект основательно завязан.

В общем, поправь меня, если я ошибаюсь, но я вижу, что ты уже потихонечку начинаешь изворачиваться. Как уже случалось на моей памяти, ты снова начал учить матчасть уже после того как ввязался в спор. Мне уже даже не интересно, что же за хеловорлды ты там нагуглишь. По существу, озвученная задача в Qt, с его убогой системой сигналов/слотов, решается так:

class Handler: public QThread
{
Q_OBJECT

public slots:
void dummySlot ()
{
qDebug() << currentThreadId() << sender()->objectName();
}
};

Далее стартуешь потоки, определенные классом Handler, цепляешь сигналы и все просто работает. А теперь экстраполируй это на управление несколькими параллельными TCP-сессиями или, если сложно абстрагироваться от кнопочек, - на окна с независимыми параллельными event loop'ами. Может тогда ты поймешь, что система событий Qt все-таки не такое дерьмо, каким тебе она тебе показалось. А может и не поймешь, C++ ведь плохой язык, верно?

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

>На ACE у меня как минимум один проект основательно завязан

что говорит явно не в твою пользу, увы

>ты уже потихонечку начинаешь изворачиваться

>Мне уже даже не интересно, что же за хеловорлды ты там нагуглишь

>сложно абстрагироваться от кнопочек

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

>система событий Qt все-таки не такое дерьмо, каким тебе она тебе показалось

такое-такое. тебе в этом треде это объяснили уже больше одного раза, а до тебя всё никак не доходит. или ты хочешь чтобы ещё я тебе дал ТЗ, а? сыграем на этот раз на моём поле?

>C++ ведь плохой язык, верно?

верно

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

> ...за такое в приличном обществе морду бьют

Это ЛОР. Если бы каждому здесь воздалось за заслуги, форум был бы стерилен. Но если так уж хочется, то приезжай на Петровско-Разумовскую завтра, в 12.00. Это в Москве.

> ...держась твоего не слишком удачного ТЗ

Не было никакого ТЗ. Была в общих чертах описана задача по составлению части кода, позволяющего связать событие с несколькими обработчиками, выполняющимися в различных потоках. При этом в обработчике должен идентифицироваться источник события. В результате ты помимо флеймоопасных нравоучений предоставил код, напоминающий кусок богомерзкого г**на.

> сыграем на этот раз на моём поле?

Я не доказывал тебе ущербности Tcl/Tk - это само по себе глупо, тем более если учесть, что я не слишком разбираюсь в этом (возьми на заметку). Поэтому "игра на твоем поле" ничего не скажет мне, кроме общих, давно понятных каждому вещей в духе "удалить папку с файлами на баше проще, чем на ассемблере" (разумеется из этого также следует, что ассемблер - дерьмо).

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

>Кстати, а давай для интереса отойдем от нелепых и абстрактных задач и напишем по куску кода: ты - на чем хочешь, из того, что ты ставил в пример в этом треде, а я на Qt. Задача следующая: нужно по событию (например, клик на кнопке, не важно) одновременно вызвать одинаковые его обработчики, находящиеся в 10 различных потоках. Задача обработчика - узнать источник сигнала и что-нибудь с ним сделать (например, сменить текст на кнопке, но только если источником сигнала действительно была кнопка)

>Была в общих чертах описана задача по составлению части кода, позволяющего связать событие с несколькими обработчиками, выполняющимися в различных потоках. При этом в обработчике должен идентифицироваться источник события

ты предложил поиграться в задачки по твоим правилам. от каждого - по такому вот коду. я намекнул, что потоки тут не обязательны, ты с достойным упорством на них настоял. я написал код, полностью соответствующий твоей постановке - полный код, с GUI, с 10 потоками и обработкой. его можно скормить интерпретатору и убедиться что он работает, причём именно так, как надо. что ты мне написал в ответ? одну очевидную строчку и "объяснения" как писать остальное?

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

>В результате ты помимо флеймоопасных нравоучений предоставил код, напоминающий кусок богомерзкого г**на.

ты же не знаешь Tcl/Tk. как ты это, интересно, оценил? по внешнему виду? или может даже запустить попробовал? ты хотел посмотреть как это выглядит на других языках - на, лови, разбирайся

>Я не доказывал тебе ущербности Tcl/Tk - это само по себе глупо, тем более если учесть, что я не слишком разбираюсь в этом (возьми на заметку)

код ты оценил тем не менее без проблем. не помешало, значит

ещё раз: мне не интересно спорить с тобой про Qt vs Tcl/Tk. мне интересно было спорить про реализацию событий. я всё же могу тебе дать задачку _именно на события_, чтобы ты попробовал хоть что-то сегодня написать. могу и на event-driven, чтобы можно было оценить необходимость потоков в этой задаче. и на reactive, чтобы можно было заодно на фильтры событий из Qt посмотреть. и на проактивную модель средствами Qt

>Но если так уж хочется, то приезжай на Петровско-Разумовскую завтра, в 12.00. Это в Москве.

увы, я в Киеве и завтра у меня семинар. я буду в Москве где-то в десятых числах июня, буду рад тебя там увидеть

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

Не проверял, возможно мелкие косяки есть

#include <QApplication>
#include <QThread>
#include <QPushButton>

class Handler: public QThread
{
    Q_OBJECT

    public slots:
        void dummySlot ()
        {
            qDebug() << currentThreadId() << sender()->objectName();
        }
};

int main (int argc, char* argv[])
{
    QApplication app(argc, argv);

    QPushButton button("Push me");

    Handler *handler;
    for (int i = 0; i < 10; ++i)
    {
        handler = new Handler;
        handler->moveToThread(handler);
        handler->start();
        QObject::connect(&button, SIGNAL(clicked()), handler, SLOT(dummySlot()));
    }

    button.show();

    return app.exec();
}

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

>Не проверял, возможно мелкие косяки есть

вот это другое дело, да. благодарю. на удивление неплохо вышло

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

однако текст на кнопке ты не меняешь, так что это ещё не решение. сможешь поменять текст на дерево виджетов для кнопки (т.е. root window->button1, что-то вроде,- чтобы она сама отдавала эти данные)? тогда будет один к одному функционал из моего примера

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

> Далее стартуешь потоки, определенные классом Handler, цепляешь сигналы и все просто работает.

Ну это какбе макрос был, который разворачивается в main :)

mannaz
()

из удалённых

>Ну если на tcl/tk ктото напишет другую не совместимую с bind реализацию сигналов/слотов, то возникнут такие же проблемы.

как показывает опыт того же Snit, на Tcl очень сложно написать что-то несовместимое. т.е. прикрутить что угодно к чему угодно - это тут забесплатно, ради этого язык и создавался. в результате, правда, пострадала производительность и модульность

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

> Честно говоря так и не осилил что такое сигналы/слоты в Qt

Это тревожный звоночек :) Проще и удобней, по-моему, некуда. А то, что язык можно расширить (а QT именно расширение) так это жирный +. Тащить все в изначальный язык - нафег, CL тому яркий пример.

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

>Инкапсуляция не нарушается если можно было делать как в gtkmm: использовать произвольный функциональный объект для обработки сигнала. А система сигналов/слотов Qt приводит к написанию однострочных слотов. Добавление таких однострочных слотов ведёт к правке соотвествующего загловочного файла, что в свою очередь ведёт к перекомпиляции всех файлов, которые его включают.

Неожиданно и даже как-то странно: аргументированный ответ. Принято. С другой стороны если мне память не изменяет о слотах того или иного объекта написано в его метаинформации. Это должно по сути дать тебе возможность узнать куда объект может принимать сигналы и при этом не лезть в дебри его внутренней реализации. Впрочем моей фантазии уже начинает не хватать для того чтобы понять зачем это надо.

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

OK, я наконец-то добрался до своего компа, запустил твой код, а заодно познакомился поближе с Tcl/Tk - очень хорошая, к слову вещь, для своей области применения. Итак, что же я вижу:

1. Реализация потребовала от тебя дополнительных извращений с какими-то "промежуточными" событиями - FAIL; 2. Контекст события вручную передается в поток-обработчик - FAIL; 3. Не смотря все эти извращения, реальный обработчик события (тот который меняет текст на кнопке) всегда выполняется в основном потоке - EPIC FAIL;

Таким образом, ты не выполнил и 50% так называемого "ТЗ". Кроме того, даже если закрыть глаза на все озвученные недочеты, утверждение, что твой код напоминает кусок богомерзкого г**на все еще остается в силе.

Я прекрасно осознаю, что реализация потоков в скриптовом языке не может быть безболезненной. Более того, потоки в Tcl/Tk, насколько мне позволяют судить приобретенные 15 мин. назад знания, выполняются в отдельной среде интерпретатора, что добавляет проблем. Но объясни мне, пожалуйста, какого черта нужно было при всех этих недостатках и убогом собственном коде поливать дерьмом Qt? Задачи, связанные с обменом событиями между параллельными event loop'ами - это реальное, серьезное применение системы сигналов/слотов. Tcl/Tk - это отличный инструмент для быстрого создания формочек и кнопочек. Его система событий полностью отвечает этому назначению, но не более.

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

>1. Реализация потребовала от тебя дополнительных извращений с 
какими-то "промежуточными" событиями - FAIL;

ты полной реализации так и не предоставил. промежуточных событий там 
нет, там пинг-понг между потоками. который был в твоём ТЗ, и которого нет в твоём коде

>2. Контекст события вручную передается в поток-обработчик - FAIL;

поясни нормально. лучше с куском кода - что именно тебе не нравится

>3. Не смотря все эти извращения, реальный обработчик события (тот 
который меняет текст на кнопке) всегда выполняется в основном потоке - 
EPIC FAIL; 

package require Thread

wm geometry . 200x100+0-0
wm resizable . 0 0

set b [button .b -text "Push Me"]
place $b -in . -relwidth 1 -relheight 1

set mainID [thread::id]

set threads []

for {set x 0} {$x < 10} {incr x} {
   lappend threads [thread::create {
               proc print {id w} {
		   thread::send -async $id [list $w configure -text "$w"]
               }
            thread::wait
            }]
}

foreach th $threads {
   bind $b <ButtonRelease-1> { thread::send -async $th [list print $::mainID [list %W]] }
}

vwait forever

пока ты не покажешь реализацию "выполнения в дочернем потоке" в
своём коде, общаться с тобой я не вижу смысла

>Я прекрасно осознаю, что реализация потоков в скриптовом языке не 
может быть безболезненной

а ещё ты не осознаёшь (до сих пор!) того, что для решения этой задачи
потоки вообще не нужны. я могу переписать свой код на Tcl так, чтобы
он использовал один поток. это будет куда проще текущего извращения -
производительней (без системного переключения контекста) и более
соответственно логике задачи. тебе, чтобы это продублировать в Qt,
придётся писать проактор. вручную. в Qt его нет, а ACE (или asio) 
использовать для такой задачи - как-то перебор. ведь в Qt такая 
хорошая система работы с событиями

ты будешь предоставлять полный код хотя бы по собственному ТЗ? или
только тявкать способен?

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

>Tcl/Tk - это отличный инструмент для быстрого создания формочек и кнопочек. Его система событий полностью отвечает этому назначению, но не более.

тебе рассказать на чём AOLServer написан? тебя ждёт откровение

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

>реальный обработчик события (тот который меняет текст на кнопке) всегда выполняется в основном потоке - EPIC FAIL;

да, кстати. к вопросу. если ты не понял - обработчик работает в своём потоке, в родительском потоке происходит только запись. что позволяет избежать дедлоков и прочих race conditions. "кнопка" находится в thread local storage родительского потока, в котором есть event loop с операциями записи. с очередью событий

всё ещё жду кода, да

jtootf ★★★★★
()

>There is a further limitation (imposed by most of the underlying database-specific libraries used by Qt). As a general rule, connections cannot be shared by multiple threads. This means you cannot simply create a pool of connections on startup and hand them out to various threads as needed. Instead, each thread must establish and maintain its own connection, within its own context. To do otherwise is undefined, and probably disastrous

про потоки (раз уж о них зашла речь) и доступ к БД в Qt. доставляет

jtootf ★★★★★
()

впрочем, в моём коде с потоками таки есть серьёзная ошибка. как
хорошо, что никто её не заметил :) подозреваю, что и не заметит

wm geometry . 200x100+0-0
wm resizable . 0 0

set b [button .b -text "Push Me"]
place $b -in . -relwidth 1 -relheight 1

proc a {w} {
   $w configure -text "A $w"
   puts "A $w"
   
   vwait forever
}

bind $b <ButtonRelease-1> "a %W"

вот пример параллельной обработки без использования потоков. обработчик не возвращается в основной цикл выполнения (по сути там вечный цикл),
однако параллельно будет выполнено столько обработчиков, сколько нужно

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

>P.S. Не нужно воспринимать это как очередной замер e-пинусов - мне действительно интересно каким образом решаются подобные задачи в других языках/фреймворках, а также, но в меньшей степени - насколько хорошо это будет выглядеть в виде кода.

с учётом твоих регулярных оскорбительных выпадов иначе это уже не воспринимается (походу и не задумывалось); тем не менее, хотелось бы нормальной задачи на "многопоточную обработку с сигналами". пример с кнопочкой немножко не в тему, ибо потоки там и правда нафиг не нужны. ты там про TCP что-то говорил? вот на TCP жизненную бы задачку. только чтобы ты её потом на Qt написал, да. интересно, что же за задачи подобным образом решаются средствами Qt. хочу, так сказать, горизонт расширить. уважишь старика, поделишься задачкой? :)

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

>Это тревожный звоночек :) Проще и удобней, по-моему, некуда.

А Gtk сигналы я сразу понял... =) По мне так они проще.

>а QT именно расширение) так это жирный +. Тащить все в изначальный язык - нафег

C++ жирн настолько, что ему уже ничего не страшно.

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

>Протух бенчмарк.

бенч - фигня, не о производительности речь (впрочем, для современных libsig++ и Qt, думаю, разница будет такой же). по существу фич мало что изменилось. или нет?

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

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

package require Thread

wm geometry . 200x100+0-0
wm resizable . 0 0

set b [button .b -text "Push Me"]
place $b -in . -relwidth 1 -relheight 1

set mainID [thread::id]

set threads []

for {set x 0} {$x < 10} {incr x} {
   lappend threads [thread::create {
               proc print {id w} {
	           puts  "[thread::id] $w"
	       
		   thread::send -async $id [list $w configure -text "$w"]
               }
            thread::wait
            }]
}

proc dispatch {w} {
    foreach th $::threads {    
        thread::send -async $th [list print $::mainID [list $w]]
    }
}

bind $b <ButtonRelease-1> { dispatch %W }

vwait forever

люто, бешено жду кода от тебя

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

так. польза от срача таки есть

во-первых, Tk bind не умеет собственноручно диспетчеризовать событие нескольким обработчикам. это чертовски неприятно в смысле reactive программирования (хотя и очень просто решается руками на уровне Tcl), и я подумаю как это можно пропатчить в Tk Core

во-вторых, объекты Tk (официально по причине плохой поддержки многопоточности в X) не могу быть разделены между потоками, т.е. существуют только в потоке-родителе. любые другие данные (TCP-сессия например) разделяются (tsv::set, tsv::get), так что в реальных примерах это ограничение не является существенным. для объектов Tk (как в рассматриваемой ситуации) можно использовать callback'и. обработка (всё, что предшествует непосредственно записи) может выполнятся в различных потоках и для объектов Tk

для потоков ввода-вывода (e.g., опять же, TCP) есть возможность не только разделения, но и балансировки между потоками средствами Tcl Threads. такие дела

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

>особо в тред не вникал, замечу лишь, что в PyQt любой метод библиотечных классов является слотом

умные люди делали PyQt

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