0

I am learning Qt and create a small example like this.

table

I have read some suggested questions which relate to my problem here but right now they are not easy for me to understand.

This is my code, above function is calendar interaction, below function is for showing items:

SmallExample::SmallExample(QWidget *parent)
     : QWidget(parent)
{
    .........
    connect(ui.tableWidget, SIGNAL(itemDoubleClicked(QTableWidgetItem*)), this, SLOT(calendar_clicked(QTableWidgetItem*)));
}

void SmallExample::calendar_clicked(QTableWidgetItem* tableitem) 
{
    int column = tableitem->column();
    SmallExample::row = tableitem->row();

    if (column == 2) {
        if (!calendar) {
            calendar = new QCalendarWidget();
        }
        calendar->setWindowTitle("Calendar");
        calendar->setWindowModality(Qt::WindowModal);
        calendar->show();
        connect(calendar, SIGNAL(activated(const QDate&)), this, SLOT(date_selected(const QDate&)));
    }
}

void SmallExample::date_selected(const QDate&)
{
    QTableWidgetItem *itemcalendar = new QTableWidgetItem;
    QIcon icon(":/icon/calendar.jpg");
    itemcalendar->setIcon(icon);
    SmallExample::ui.tableWidget->setItem(SmallExample::row, 0, itemcalendar);

    QString text= SmallExample::calendar->selectedDate().toString("dd.MM.yyyy");
    QTableWidgetItem *datetext = new QTableWidgetItem;
    datetext->setText(text);
    SmallExample::ui.tableWidget->setItem(SmallExample::row, 0, datetext);
    SmallExample::calendar->close();
}

I know when datetext is added, the itemcalendar will be overwritten, so it does not appear any more. I want both of which will appear, but I don't know how to solve this. Thanks in advance!

update code:

void SmallExample::date_selected(const QDate&)
{
    QTableWidgetItem *itemcalendar = SmallExample::ui.tableWidget->item(SmallExample::row, 2);
    QIcon icon(":/icon/calendar.jpg");
    itemcalendar->setIcon(icon);
    QString date = SmallExample::calendar->selectedDate().toString("dd.MM.yyyy")
    itemcalendar->setText(date);

}
songvan
  • 369
  • 5
  • 21
  • Did you try to set text and icon to the same QTableWidgetItem* ? – Frodon Jul 18 '16 at 07:20
  • @Frodon: Yes, that is what i want to do as in the table. But according to my code, first icon is set, but when text is set, it overwrite icon, so icon is not there any more. Or in other word, with my code, one time i can set only one thing to the cell. :( – songvan Jul 18 '16 at 07:26
  • In your code you overwrite the item at `(SmallExample::row, 2)` by a new `QTableWidgetItem*` instance. You should reuse the same instance: `itemcalendar->setText(date);` – Frodon Jul 18 '16 at 08:03
  • thanks Frodon, your idea is as same as Bearded's idea below. But it does not work for me, maybe because I have calendar interaction in my code. – songvan Jul 18 '16 at 08:25

3 Answers3

2

Maybe you should consider using a QStyledItemDelegate for the second column of your table.

See this post and the star example from Qt documentation.

Here is a code sample:

class CalendarDelegate : public QStyledItemDelegate
{
public:
 CalendarDelegate (QObject *parent = 0) : 
  QStyledItemDelegate(parent)
 {
 }

void CalendarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                             const QModelIndex &index) const
 {
   painter->save();
   QIcon icon(":/icon/calendar.jpg");
   QSize iconsize = option.decorationSize;

   painter->drawPixmap(0.0, 0.0, icon.pixmap(iconsize.width(), iconsize.height()));

   painter->restore();
  }
}

And then in the SmallExample class constructor:

SmallExample::ui.tableWidget->setItemDelegateForColumn(2, new CalendarDelegate(this));
Community
  • 1
  • 1
Frodon
  • 3,684
  • 1
  • 16
  • 33
1

This is how your code should look like:

QTableWidgetItem *itemcalendar = new QTableWidgetItem;
QIcon icon(":/icon/calendar.jpg");
itemcalendar->setIcon(icon);
itemcalendar->setText(SmallExample::calendar->selectedDate().toString("dd.MM.yyyy"));
SmallExample::ui.tableWidget->setItem(SmallExample::row, 2, itemcalendar);

I have just tried this example and it works as expected (both text and icon appears in item) no matter in which order I set icon and text.

You don't have to create new item evety time you choose date in date_selected, use item as Kirill suggested:

QTableWidgetItem *itemcalendar = SmallExample::ui.tableWidget->item(SmallExample::row, 2);
QString date = SmallExample::calendar->selectedDate().toString("dd.MM.yyyy");
itemcalendar->setText(date);
Bearded Beaver
  • 646
  • 4
  • 21
  • thank you Bearded, but by my side, this code does not work. After clicking to the calendar icon and choose date, the icon does not appear any more since then, only text appears. I guess problem comes from calendar interaction. If we set `itemcalendar->setText("bla bla bla")` it works, but here i have a calendar interaction. Am I right ? – songvan Jul 18 '16 at 08:18
  • @amateur please show the code called after clicking the calendar icon and choosing date. – Bearded Beaver Jul 18 '16 at 08:24
  • @amateur you overwrite icon every time you set new item in date_selected. See updates in my anwser – Bearded Beaver Jul 18 '16 at 08:44
  • I updated my code above as you guys suggested. But the problem is still the same, after clicking calendar icon and double klick to the date, the icon is not there any more (forever), only date text appears. Maybe problem comes from somewhere else... – songvan Jul 18 '16 at 08:59
  • @amateur the problem comes from somewhere else, I've tried your new code and it works. The only edit needed - you don't have to connect activated(const QDate&) with date_selected every time you call calendar_clicked. Do it just once right after calendar = new QCalendarWidget(); Now you perform new connection in every calendar_clicked call and so one signal leads to a number of date_selected calls. Try to place qDebug()<<"called" in the beginning of the date_selected and check this. – Bearded Beaver Jul 18 '16 at 09:15
  • well, this point is precious. Sadly I can still not imagine your idea because i don't have any for loop here. So how can I connect just only once activated() and date_selected() ? Could you please update the code according to your idea ? – songvan Jul 18 '16 at 10:26
1

If you set one time only icon and another time text, you can try such code, with item method:

QTableWidgetItem *itemcalendar = new QTableWidgetItem;
QIcon icon(":/icon/calendar.jpg");
itemcalendar->setIcon(icon);
SmallExample::ui.tableWidget->setItem(SmallExample::row, 2, itemcalendar);

...

QTableWidgetItem* itemcalendar = SmallExample::ui.tableWidget->item(SmallExample::row, 2);
itemcalendar->setText(date);
Kirill Chernikov
  • 1,387
  • 8
  • 21
  • thanks for your solution. I updated my code as you suggested. But after clicking calendar icon and double klick to the date, the icon is not there any more (forever), only date text appears. :( – songvan Jul 18 '16 at 09:00
  • As you provide more code, it became clear, that it will be helpful for you to use [QStyledItemDelegate](http://doc.qt.io/qt-5/qstyleditemdelegate.html) for calendar interaction. Qt example: http://doc.qt.io/qt-5/qtwidgets-itemviews-stardelegate-example.html – Kirill Chernikov Jul 18 '16 at 09:10