Bug #6102
closedCan't chain signals from children up to parent widget
0%
Description
Hi,
I have problem with Planner example after some modifications
@
WWidget* PlannerCalendar::renderCell(WWidget* widget, const WDate& date)
{
if (!widget)
{
widget = new CalendarCell();
}
CalendarCell* cc = (CalendarCell*)widget;
cc->update(user_, date);
cc->cellWasModified().connect(this, &PlannerCalendar::calendarWasModified); // this part gives error
/*
*cellWasModified() returns signal which I want to chain to 2nd function calendarWasModified() which should emit signal herself when triggered
- up to 3rd widget (parent) but I'm stuck. I get this error in the compiler
*/
return cc;
}
@
error:
In file included from /usr/local/include/Wt/WSignal.h:13:0,
from /usr/local/include/Wt/WWidget.h:14,
from /usr/local/include/Wt/WCompositeWidget.h:10,
from /usr/local/include/Wt/WCalendar.h:10,
from ../PlannerCalendar.h:14,
from ../PlannerCalendar.cpp:7:
/usr/local/include/Wt/Signals/signals.hpp: In instantiation of 'struct Wt::Signals::Impl::function_traits<Wt::SignalWt::WString& (PlannerCalendar::*)()>':
/usr/local/include/Wt/Signals/signals.hpp:444:14: required from 'Wt::Signals::connection Wt::Signals::Impl::connectFunction(Wt::Signals::Signal<Args ...>&, typename std::enable_if<(! std::is_bind_expression::value), const F&>::type, const Wt::Core::observable*) [with F = Wt::SignalWt::WString& (PlannerCalendar::)(); Args = {Wt::WString}; Wt::Signals::connection = Wt::Signals::Impl::Connection; typename std::enable_if<(! std::is_bind_expression::value), const F&>::type = Wt::SignalWt::WString& (PlannerCalendar::* const&)()]'
/usr/local/include/Wt/WSignal.h:656:49: required from 'Wt::Signals::connection Wt::Signal::connect(const Wt::WObject, const F&) [with F = Wt::SignalWt::WString& (PlannerCalendar::)(); A = {Wt::WString}; Wt::Signals::connection = Wt::Signals::Impl::Connection]'
../PlannerCalendar.cpp:32:76: required from here
/usr/local/include/Wt/Signals/signals.hpp:302:58: error: 'operator()' is not a member of 'Wt::SignalWt::WString& (PlannerCalendar::*)()'
struct function_traits : public function_traits<decltype(&Function::operator())>
^
/usr/local/include/Wt/Signals/signals.hpp: In instantiation of 'Wt::Signals::connection Wt::Signals::Impl::connectFunction(Wt::Signals::Signal<Args ...>&, typename std::enable_if<(! std::is_bind_expression::value), const F&>::type, const Wt::Core::observable) [with F = Wt::SignalWt::WString& (PlannerCalendar::)(); Args = {Wt::WString}; Wt::Signals::connection = Wt::Signals::Impl::Connection; typename std::enable_if<(! std::is_bind_expression::value), const F&>::type = Wt::SignalWt::WString& (PlannerCalendar::* const&)()]':
/usr/local/include/Wt/WSignal.h:656:49: required from 'Wt::Signals::connection Wt::Signal::connect(const Wt::WObject, const F&) [with F = Wt::SignalWt::WString& (PlannerCalendar::)(); A = {Wt::WString}; Wt::Signals::connection = Wt::Signals::Impl::Connection]'
../PlannerCalendar.cpp:32:76: required from here
/usr/local/include/Wt/Signals/signals.hpp:444:14: error: 'argCount' is not a member of 'Wt::Signals::Impl::function_traits<Wt::SignalWt::WString& (PlannerCalendar::*)()>'
::connect(signal, target, Signals::Impl::toFunction(function));
^
/usr/local/include/Wt/Signals/signals.hpp: In instantiation of 'struct Wt::Signals::Impl::function_traits<Wt::SignalWt::WString& (PlannerCalendar::* const)()>':
/usr/local/include/Wt/Signals/signals.hpp:313:46: required by substitution of 'template typename Wt::Signals::Impl::function_traits::function Wt::Signals::Impl::toFunction(Function&) [with Function = Wt::SignalWt::WString& (PlannerCalendar::* const)()]'
/usr/local/include/Wt/Signals/signals.hpp:444:56: required from 'Wt::Signals::connection Wt::Signals::Impl::connectFunction(Wt::Signals::Signal<Args ...>&, typename std::enable_if<(! std::is_bind_expression::value), const F&>::type, const Wt::Core::observable) [with F = Wt::SignalWt::WString& (PlannerCalendar::)(); Args = {Wt::WString}; Wt::Signals::connection = Wt::Signals::Impl::Connection; typename std::enable_if<(! std::is_bind_expression::value), const F&>::type = Wt::SignalWt::WString& (PlannerCalendar::* const&)()]'
/usr/local/include/Wt/WSignal.h:656:49: required from 'Wt::Signals::connection Wt::Signal::connect(const Wt::WObject, const F&) [with F = Wt::SignalWt::WString& (PlannerCalendar::)(); A = {Wt::WString}; Wt::Signals::connection = Wt::Signals::Impl::Connection]'
../PlannerCalendar.cpp:32:76: required from here
/usr/local/include/Wt/Signals/signals.hpp:302:58: error: 'operator()' is not a member of 'Wt::SignalWt::WString& (PlannerCalendar::* const)()'
struct function_traits : public function_traits<decltype(&Function::operator())>
^
/usr/local/include/Wt/Signals/signals.hpp: In instantiation of 'Wt::Signals::connection Wt::Signals::Impl::connectFunction(Wt::Signals::Signal<Args ...>&, typename std::enable_if<(! std::is_bind_expression::value), const F&>::type, const Wt::Core::observable) [with F = Wt::SignalWt::WString& (PlannerCalendar::)(); Args = {Wt::WString}; Wt::Signals::connection = Wt::Signals::Impl::Connection; typename std::enable_if<(! std::is_bind_expression::value), const F&>::type = Wt::SignalWt::WString& (PlannerCalendar::* const&)()]':
/usr/local/include/Wt/WSignal.h:656:49: required from 'Wt::Signals::connection Wt::Signal::connect(const Wt::WObject, const F&) [with F = Wt::SignalWt::WString& (PlannerCalendar::*)(); A = {Wt::WString}; Wt::Signals::connection = Wt::Signals::Impl::Connection]'
../PlannerCalendar.cpp:32:76: required from here
/usr/local/include/Wt/Signals/signals.hpp:444:56: error: no matching function for call to 'toFunction(Wt::SignalWt::WString& (PlannerCalendar::* const&)())'
::connect(signal, target, Signals::Impl::toFunction(function));
^
/usr/local/include/Wt/Signals/signals.hpp:313:46: note: candidate: template typename Wt::Signals::Impl::function_traits::function Wt::Signals::Impl::toFunction(Function&)
typename function_traits::function toFunction(Function& lambda)
^
/usr/local/include/Wt/Signals/signals.hpp:313:46: note: substitution of deduced template arguments resulted in errors seen above
make: * [PlannerCalendar.o] Error 1
subdir.mk:45: recipe for target 'PlannerCalendar.o' failed
Files
Updated by Grzesiek Buraczewski about 7 years ago
cc->cellWasModified().connect(std::bind(&PlannerCalendar::calendarWasModified, this ));
std::bind fixed it for me, but why i got this error without bind ??
Updated by Roel Standaert about 7 years ago
- Status changed from New to Feedback
Could you provide a more complete example, maybe a patch file with all of your changes? I've tried it out, and it seems to be compiling fine on my end. (I'm on Ubuntu 16.04 with GCC 5.4, by the way.)
Updated by Grzesiek Buraczewski about 7 years ago
I have the same spec. Ubuntu 16.04 , gcc 5.4.1
// This may look like C code, but it's really -*- C++ -*-
/*
* Copyright (C) 2010 Emweb bvba, Kessel-Lo, Belgium.
*
* See the LICENSE file for terms of use.
*/
#ifndef CALENDAR_CELL_H_
#define CALENDAR_CELL_H_
#include "UserAccount.h"
#include <Wt/WContainerWidget.h>
//debuging
#include <iostream>
using namespace Wt;
class CalendarCell : public WContainerWidget
{
public:
CalendarCell();
void update(const dbo::ptr<UserAccount>& user, const WDate& date);
WDate date() {return date_; }
dbo::ptr<UserAccount> user() { return user_; }
Signal<WString>& cellWasModified() { std::cout << "from CalendarCell" << std::endl; return cellModified_;}; //hard coded
Signal<WString> cellModified_;
private:
WDate date_;
dbo::ptr<UserAccount> user_;
std::unique_ptr<WDialog> dialog_;
void showEntryDialog();
void showAllEntriesDialog();
};
#endif //CALENDAR_CELL_H_
/*
* Copyright (C) 2010 Emweb bvba, Kessel-Lo, Belgium.
*
* See the LICENSE file for terms of use.
*/
#include "CalendarCell.h"
#include "EntryDialog.h"
#include "AllEntriesDialog.h"
#include "Login/PlannerApplication.h"
#include "Entry.h"
#include <Wt/WDate.h>
#include <Wt/WText.h>
#include <Wt/WSignal.h>
#include <string>
CalendarCell::CalendarCell()
: WContainerWidget()
{
resize(100, 120); // single cell size
setStyleClass("cell");
setToolTip(tr("calendar.cell.tooltip"));
clicked().connect(this, &CalendarCell::showEntryDialog);
}
void CalendarCell::update(const dbo::ptr<UserAccount>& user, const WDate& date)
{
date_ = date;
user_ = user;
//Signal
std::cout << "edit from cell" << std::endl;
cellModified_.emit(""); // hard coded for debugin
//
clear();
dbo::Session& session = PlannerApplication::plannerApplication()->session;
dbo::Transaction transaction(session);
WString day;
day += std::to_string(date.day());
if (date.day() == 1)
{
day += " " + WDate::longMonthName(date.month());
}
auto header = cpp14::make_unique<WText>(day);
header->setStyleClass("cell-header");
addWidget(std::move(header));
typedef dbo::collection< dbo::ptr<Entry> > Entries;
Entries entries = user->entriesInRange(date, date.addDays(1));
const unsigned maxEntries = 4;
unsigned counter = 0;
for (Entries::const_iterator i = entries.begin();
i != entries.end(); ++i, ++counter) {
if (counter == maxEntries) {
auto extra =
cpp14::make_unique<WText>(tr("calendar.cell.extra")
.arg((int)(entries.size() - maxEntries)));
auto extraPtr = addWidget(std::move(extra));
extraPtr->setStyleClass("cell-extra");
extraPtr->clicked().preventPropagation();
extraPtr->clicked().connect(this, &CalendarCell::showAllEntriesDialog);
break;
}
WString format = EntryDialog::timeFormat;
auto textToCell = cpp14::make_unique<WText>(
// I commented this out becase this app is not exact to hour day planer but rather
// week planing app
//(*i)->start.toString(format) +
//"-" +
//(*i)->stop.toString(format) +
/*": " + */ (*i)->summary);
//ADD color acording to status of task
if((*i)->isFinished.empty())
{
textToCell->setStyleClass("unfinished-task");
}
else
{
textToCell->setStyleClass("finished-task");
}
addWidget(std::move(textToCell));
}
transaction.commit();
}
void CalendarCell::showEntryDialog()
{
WString title =
tr("calendar.entry.title").arg(date_.toString("ddd, d MMM yyyy"));
dialog_ = cpp14::make_unique<EntryDialog>(title, this);
dialog_->show();
}
void CalendarCell::showAllEntriesDialog()
{
WString title =
tr("calendar.cell.all-entries.title")
.arg(date_.toString("ddd, d MMM yyyy"));
dialog_ = cpp14::make_unique<AllEntriesDialog>(title, this);
dialog_->show();
}
And this is the planner calendar class
// This may look like C code, but it's really -*- C++ -*-
/*
* Copyright (C) 2010 Emweb bvba, Kessel-Lo, Belgium.
*
* See the LICENSE file for terms of use.
*/
#ifndef PLANNER_CALENDAR_H_
#define PLANNER_CALENDAR_H_
#include "UserAccount.h"
#include <Wt/Dbo/Dbo.h>
#include <Wt/WCalendar.h>
#include <Wt/WSignal.h>
#include <Wt/WDate.h>
using namespace Wt;
class PlannerCalendar : public WCalendar
{
public:
PlannerCalendar(dbo::ptr<UserAccount> user);
Signal<WString>& calendarWasModified() {return calendarModified_ ;} //TODO implement its now hard coded
Signal<WString> calendarModified_;
void onlyForDebuging() {std::cout << "Debug worked in PlannerCalendar" << std::endl; calendarModified_.emit("");}
protected:
virtual WWidget* renderCell(WWidget* widget, const WDate& date) override;
private:
dbo::ptr<UserAccount> user_;
};
#endif //PLANNER_CALENDAR_H_
And .cpp file
/*
* Copyright (C) 2010 Emweb bvba, Kessel-Lo, Belgium.
*
* See the LICENSE file for terms of use.
*/
#include "PlannerCalendar.h"
#include "CalendarCell.h"
#include "Entry.h"
#include <Wt/WWidget.h>
#include <memory>
using namespace Wt;
PlannerCalendar::PlannerCalendar(dbo::ptr<UserAccount> user)
: WCalendar(),
user_(user)
{
setStyleClass(styleClass() + " calendar");
//setSelectionMode(SelectionMode::None);
}
WWidget* PlannerCalendar::renderCell(WWidget* widget, const WDate& date)
{
if (!widget)
{
widget = new CalendarCell();
}
CalendarCell* cc = (CalendarCell*)widget;
cc->update(user_, date);
cc->cellWasModified().connect(this, &PlannerCalendar::calendarWasModified);
cc->cellWasModified().connect(this ,&PlannerCalendar::onlyForDebuging);
//calendarModified_.emit(WString("tom")); //TODO hardcoded
// cc->cellWasModified().connect(this, &PlannerCalendar::calendarWasModified);
return cc;
}
I dont know how to send multiple files so i post them here.
Updated by Roel Standaert about 7 years ago
- File PlannerCalendar.h PlannerCalendar.h added
- File PlannerCalendar.C PlannerCalendar.C added
I see what you're doing wrong: you are trying to connect the cellWasModified()
signal to a method that returns a Signal
. That's not how you should do that: you have to connect it to a method that returns void
, and emits the cellWasModified()
signal, see the modified files I attached.
Updated by Roel Standaert about 7 years ago
- Status changed from Feedback to Closed
Closing this since it's not an issue with Wt.