Название: connect и динамический отправитель Отправлено: Rosster от Апрель 26, 2013, 14:59 Всем привет. У меня в connect отправитель все время меняется. Вот пример:
Код: Class Main Есть ли решение? Второй вопрос: почему даже если я поставлю в классе Main доступ private slots, то компилятор не ругнется и программа при запуске сработает нормально, хотя connect не имеет права уже этот метод использовать? Спасибо. P.S. Сорри за краткость и неполноту кода, главное что смысл понятен. Название: Re: connect и динамический отправитель Отправлено: Serr500 от Апрель 26, 2013, 15:24 QMetaObject::invokeMethod (http://qt-project.org/doc/qt-4.8/qmetaobject.html#invokeMethod) не подойдёт?
Название: Re: connect и динамический отправитель Отправлено: m_ax от Апрель 26, 2013, 15:44 Может и не нужны никакие сигналы?
Можно сделать так, как вариант: Код
Название: Re: connect и динамический отправитель Отправлено: mutineer от Апрель 26, 2013, 15:48 Для слота не принципиально private он или public, потому что при вызове через сигнал/слот вызывает слот сам объект-владелец слота, а не кто-то снаружи.
Твое решение не работает, потому что connect привязывается к конкретному объекту в момент коннекта, а не в момент испускания сигнала. Рассматривай варианты выше Название: Re: connect и динамический отправитель Отправлено: Rosster от Апрель 26, 2013, 16:22 QMetaObject::invokeMethod (http://qt-project.org/doc/qt-4.8/qmetaobject.html#invokeMethod) не подойдёт? Можно поподробней? Почитал про него, он нужен при потоках и просто вызывает слот.Тоже самое я могу сделать в слотеMainWindow::add() {QMetaObject::invokeMethod(main, "add");} вместо MainWindow::add() {main->add();} Или я чет не догоняю? Может и не нужны никакие сигналы? Не подойдет. У меня sender - это кнопка в интерфейсе, кнопка мультизадачная, на нее нужно повесить слот add(), который вызывается на другом виджете.Короче это похоже на задачу: одна кнопка "добавить запись" и куча виджетов для которых эта кнопка пригодится. Название: Re: connect и динамический отправитель Отправлено: m_ax от Апрель 26, 2013, 16:34 Не подойдет. У меня sender - это кнопка в интерфейсе, кнопка мультизадачная, на нее нужно повесить слот add(), который вызывается на другом виджете. Короче это похоже на задачу: одна кнопка "добавить запись" и куча виджетов для которых эта кнопка пригодится. Если sender в курсе (в смысле знает) у какого именно объекта в данный момент должен быть вызван слот, то проблемы не вижу.. Сигнал кнопки можно повесить на слот (как некий посредник), в котором уже вызывать std::function с нужным указателем на виджет... Название: Re: connect и динамический отправитель Отправлено: mutineer от Апрель 26, 2013, 17:02 QMetaObject::invokeMethod (http://qt-project.org/doc/qt-4.8/qmetaobject.html#invokeMethod) не подойдёт? Можно поподробней? Почитал про него, он нужен при потоках и просто вызывает слот.Тоже самое я могу сделать в слотеMainWindow::add() {QMetaObject::invokeMethod(main, "add");} вместо MainWindow::add() {main->add();} Или я чет не догоняю? 1) Он нужен не только при потоках, а и например тогда, когда нужно вызвать метод по его строковому имени у неизвестного QObject 2) Сделать можешь, но если main указывает на QObject, то придется кастить Название: Re: connect и динамический отправитель Отправлено: Rosster от Апрель 26, 2013, 18:58 Сигнал кнопки можно повесить на слот (как некий посредник), в котором уже вызывать std::function с нужным указателем на виджет... Сделать можешь, но если main указывает на QObject, то придется кастить У меня уже есть посредник (смысл мне в std::function?), сейчас я и пишу:Код: MainWindow::MainWindow() Тока как я и говорил если у меня куча кнопок а также виртуальных функций,мне для каждого делать посредника? Не люблю лишних функций Раз нельзя сделать динамический connect, то как это обойти даже с помощью QMetaObject::invokeMethod() я не понял. Название: Re: connect и динамический отправитель Отправлено: Bepec от Апрель 26, 2013, 20:42 Rosster, опиши пожалуйста в общих словах, что ты хочешь сделать. Если нехватает слов, нарисуй.
PS ваша проблема скорее всего происходит из плохой архитектуры. Расскажите свою идею, а мы (ну или только я) подскажу как её можно реализовать просто и наглядно. Название: Re: connect и динамический отправитель Отправлено: Rosster от Апрель 26, 2013, 21:20 Хорошо:) Есть QMainWindow. На нем штук 10 кнопок. В QTabWidget куча вкладок с виджетами. Их может быть и 3 и 10. И каждый виджет должен работать с этими кнопками. Поэтому было принято решение наследоваться этим виджетам от главного, в котором виртуальные функции для каждой из кнопок. Благодаря этому каждому виджету придется (и это правильно) работать с этими кнопками. В итоге такой код:
Код: Class Manager : public QWidget Получается для add(), del() и т.д. нужно писать отдельный слот. Для типичной реализации нужно для трех классов писать кучу слотов. Причем MainWindow - посредник. Получается как минимум некрасивый код. Название: Re: connect и динамический отправитель Отправлено: thechicho от Апрель 28, 2013, 17:34 Manager *_manager;
manager = ui->listWidget; чот я нифига не понял. есть QMainWindow. на нем QTabWidget. на какой-то вкладке есть QListWidget так же на QMainWindow есть кнопка добавить pushButtonAdd MainWindow::on_pushButtonAdd_clicked() { if (ui->tabWidget->currentIndex() == 0) { .... } else if (ui->tabWidget->currentIndex() == 1) { ui->listWidgetN->addItem(ui->lineEditN->text()); } else if (ui->tabWidget->currentIndex() == N) { ... } } Название: Re: connect и динамический отправитель Отправлено: Bepec от Апрель 28, 2013, 21:16 Кхм. Правильно я всё таки спросил :D
У вас вот какая ситуация (если неправ, поправьте). Имеются кнопки, которые должны работать с одним виджетом единовременно и со всеми, скажем так, параллельно. Зачем вам выносить этот код в каждый виджет? Сделайте проще - 3 слота (add, delete, insert, допустим). И в каждом не жёстко задаёте свой виджет, а используете лишь текущий видимый. Т.е. примерно так (псевдокод) Код: void add() PS если кнопки одинаковы, то и реакция на них должна быть одинаковая? Если для каждого виджета реакция должна быть разная, тут никуда не уйти от виртуальных функций. Название: Re: connect и динамический отправитель Отправлено: Rosster от Апрель 29, 2013, 09:53 MainWindow::on_pushButtonAdd_clicked() И вот так для каждой кнопки расписывать?зачем?Виртуальная функция позволяет это все проделать одной строкой. Но все равно мой код считаю не есть гуд.{ if (ui->tabWidget->currentIndex() == 0) { .... } else if (ui->tabWidget->currentIndex() == 1) { ui->listWidgetN->addItem(ui->lineEditN->text()); } else if (ui->tabWidget->currentIndex() == N) { ... } } PS если кнопки одинаковы, то и реакция на них должна быть одинаковая? Если для каждого виджета реакция должна быть разная, тут никуда не уйти от виртуальных функций. Именно) Для каждого виджета разная. Нажатие кнопки влияет только на текущую вкладку, и этот add() для каждого виджета разный и этот метод обязателен в классе виджета.Название: Re: connect и динамический отправитель Отправлено: Bepec от Апрель 29, 2013, 10:29 Тогда от виртуальных методов никуда не деться.
Совмещайте - получаем текущий виджет и вызываем у него метод кнопочный. Не связывая слоты. Типа код: Код: // текущий виджет получаем. Название: Re: connect и динамический отправитель Отправлено: thechicho от Апрель 29, 2013, 11:37 //И вот так для каждой кнопки расписывать?зачем?Виртуальная функция позволяет это все проделать одной строкой.
как? зачем городить классы-наследники, если к виджетам уже есть доступ. можно же сразу все описать в 1 месте в зависимости от текущего индекса таба. так же будет понятнее и по "затрам" дешевле. или я не так понял задачу? if (ui->tabWidget->currentWidget() == ui->listWidget) manager = ui->listWidget; а как тут может быть равенство? QWidget * QTabWidget::currentWidget () const Returns a pointer to the page currently being displayed by the tab dialog. The tab dialog does its best to make sure that this value is never 0 (but if you try hard enough, it can be). currentWidget() возвращает же указатель на вкладку, а не на виджет, расположенный на этой вкладке (тем более их может быть несколько). или я опять не так понял? Название: Re: connect и динамический отправитель Отправлено: Bepec от Апрель 30, 2013, 08:20 Ичика, если создавать табы при помощи метода addTab(QWidget*, QString), то этот метод вернёт установленный виджет (просто при создании в дизайнере вкладки, текущим становится виджет вкладки). Так же присутствует метод setCurrentWidget.
А разбивать логику на классы необходимо. Для того, чтобы при добавлении нового виджета не надо было менять уже существующие классы. Таким образом получается система плагинов. - Можно подставить любой класс с этими методами. Название: Re: connect и динамический отправитель Отправлено: Rosster от Апрель 30, 2013, 12:28 зачем городить классы-наследники, если к виджетам уже есть доступ. Верес правильно написал: меньше ошибок, больше мобильности.можно же сразу все описать в 1 месте в зависимости от текущего индекса таба. так же будет понятнее и по "затрам" дешевле. или я не так понял задачу? Типа код: Это куда вставлять? В MainWindow::slAdd() {}? А смысл? Там стоит более логичное manager->add(); которое работает на ура.Код: // текущий виджет получаем. Название: Re: connect и динамический отправитель Отправлено: Bepec от Апрель 30, 2013, 12:41 Эммм... У вас присутствует менеджер. А я предлагаю без менеджера как бы.
Напрямую. Без левых наследований и прочего. Т.е. Код: // запихиваем ваши классы в табвиджет Название: Re: connect и динамический отправитель Отправлено: Rosster от Апрель 30, 2013, 12:53 Верес, в моем случае не подойдет, т.к. в мэнеджере еще много методов общих для всех виджетов,поэтому без него никак. Но ваш способ понадобится в более простых случаях, мне это пригодится.
Спасибо всем) Название: Re: connect и динамический отправитель Отправлено: Bepec от Апрель 30, 2013, 14:05 Кхм. Что мешает вызывать все ваши методы через способ, предложенный мной? :)
Этот метод позволяет вызвать любой слот у любого класса, наследника QWidget. С любыми параметрами. PS недоумение. Название: Re: connect и динамический отправитель Отправлено: Rosster от Апрель 30, 2013, 14:59 Кхм. Что мешает вызывать все ваши методы через способ, предложенный мной? :) Этот метод позволяет вызвать любой слот у любого класса, наследника QWidget. С любыми параметрами. PS недоумение. Верес, в моем случае не подойдет, т.к. в мэнеджере еще много методов общих для всех виджетов,поэтому без него никак. Я же написал...Мне полюбому создавать родит. класс,т.к. много ОБЩИХ методов для всех виджетов, которые я тут не расписывал. Ну а вирт. функции позволяют не забыть в каком-нибудь виджете обязательный метод.Название: Re: connect и динамический отправитель Отправлено: Bepec от Апрель 30, 2013, 15:02 Кхм... кхм.... кхм..... Ладно, не буду настаивать, делай как хочешь :D
Как грится - я дал тебе знание, теперь обрети силу :D |