Dennis
Dennis

Reputation: 186

When using QWidget-pointers in a list they cannot be showed

I'm creating a Calendar program on my PC, but I've encountered a very weird problem while creating a Widget to show Day-details.

What it should show is the selected date at the top with a previous and next button, and under that a list with QPushButton-subclasses at a 1 hour interval, but for some reason I only can get the selected date + the previous button + the next button when i'll try to run it.

It seems to be a problem that the widget-pointers are placed in a list, but it seems to be weird for me that that is a problem. But still when I tested to not use the list and hard-coding everything it worked, so why is it a problem that I place those pointers in a list?

GUICalendarDay::GUICalendarDay(QDate date)
{
    m_date = date;
    //creating buttons
    m_prevDay = new QPushButton(QString("<"));
    m_nextDay = new QPushButton(QString(">"));

    connect(m_nextDay, SIGNAL(clicked()), this, SLOT(nextDay()));
    connect(m_prevDay, SIGNAL(clicked()), this, SLOT(prevDay()));

    //creating the cells
    for(int i = 0; i++; (i<TOTALHOURS))
    {
        m_shedule[i] = new GUICalendarCell(QTime(i, 0, 0), QTime(i, 59, 59));//creating 1-hour intervals
        connect(m_shedule[i], SIGNAL(clickedRange(QTime,QTime)), this, SLOT(selectedRange(QTime,QTime)));
    }

    //creating the labels
    m_dateLabel = new QLabel(m_date.toString(QString("dd/MM/yyyy")));

    QLabel *hourLabel[TOTALHOURS];

    for(int i = 0; i++; (i<TOTALHOURS))
    {
        hourLabel[i] = new QLabel(QTime(i,0,0).toString(QString("hh:mm")));
    }


    //placing everything in a layout
    QGridLayout *mainLayout = new QGridLayout;
    mainLayout->addWidget(m_prevDay, 0, 1);
    mainLayout->addWidget(m_dateLabel, 0, 2);
    mainLayout->addWidget(m_nextDay, 0, 3);
    for(int i = 0; i++; (i<TOTALHOURS))
    {
        mainLayout->addWidget(hourLabel[i], i+1, 0);
        hourLabel[i]->show();
        mainLayout->addWidget(m_shedule[i], i+1, 1, 3, 1);
        m_shedule[i]->show();
    }
    setLayout(mainLayout);

}

It's not a really big problem, but I would like to keep my code clean and I also would like to know why this does not work.

Everything I see

Upvotes: 0

Views: 73

Answers (1)

You've switched the loop increment with the loop test in the last for loop. It should read for (int i = 0; i < TOTALHOURS; ++).

Your code has several other style issues.

  1. Use container classes, not raw arrays.

  2. You can put all the members into the class, instead of explicitly storing them on the heap.

  3. You can use a PIMPL to make the header not include implementation details.

The example below requires C++11 and Qt 5. It could be adapted to Qt 4 and C++9x through the use of Q_PRIVATE_SLOT.

// Interface (header file)

#include <QWidget>

class QDate;
class GUICalendarDayPrivate;
class GUICalendarDay : public QWidget {
   Q_OBJECT
   Q_DECLARE_PRIVATE(GUICalendarDay)
   QScopedPointer<GUICalendarDayPrivate> const d_ptr;
public:
   explicit GUICalendarDay(const QDate & date, QWidget * parent = 0);
   ~GUICalendarDay();
};

// Implementation (.cpp file)

#include <QGridLayout>
#include <QPushButton>
#include <QLabel>
#include <QDate>

// dummy to make the example compile
class GUICalendarCell : public QWidget {
   Q_OBJECT
public:
   explicit GUICalendarCell(const QTime &, const QTime &, QWidget * parent = 0) : QWidget(parent) {}
   Q_SIGNAL void clickedRange(const QTime &, const QTime &);
};

class GUICalendarDayPrivate {
public:
   QDate date;
   QGridLayout layout;
   QPushButton prevDay, nextDay;
   QLabel dateLabel;
   QList<GUICalendarCell*> schedule;

   QList<QLabel*> hourLabels;
   explicit GUICalendarDayPrivate(const QDate &, QWidget * parent);
   void onNextDay() {}
   void onPrevDay() {}
   void selectedRange(const QTime &, const QTime &) {}
};

GUICalendarDay::GUICalendarDay(const QDate &date, QWidget *parent) : QWidget(parent),
   d_ptr(new GUICalendarDayPrivate(date, this))
{}

GUICalendarDay::~GUICalendarDay() {}

GUICalendarDayPrivate::GUICalendarDayPrivate(const QDate & date_, QWidget * parent) :
   date(date_),
   layout(parent),
   prevDay("<"), nextDay(">"), dateLabel(date.toString(QString("dd/MM/yyyy")))
{
   const int TOTALHOURS = 24;
   QObject::connect(&nextDay, &QAbstractButton::clicked, [this]{ onNextDay(); });
   QObject::connect(&prevDay, &QAbstractButton::clicked, [this]{ onPrevDay(); });

   layout.addWidget(&prevDay, 0, 1);
   layout.addWidget(&dateLabel, 0, 2);
   layout.addWidget(&nextDay, 0, 3);

   for(int i = 0, row = layout.rowCount(); i<TOTALHOURS; ++i, ++row) {
      auto from = QTime(i, 0, 0), to = QTime(i, 59, 59);
      auto cell = new GUICalendarCell(from, to);
      auto hourLabel = new QLabel(from.toString(QString("hh:mm")));

      QObject::connect(cell, &GUICalendarCell::clickedRange,
                       [this](const QTime & from, const QTime & to){
         selectedRange(from, to);
      });

      schedule << cell;
      hourLabels << hourLabel;
      layout.addWidget(hourLabel, row, 0);
      layout.addWidget(cell, row, 1, 3, 1);
   }
}

// main.cpp
#include <QApplication>

int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   GUICalendarDay day(QDate::currentDate());
   day.show();
   return a.exec();
}

// Only needed if all of the example is in a single file
#include "main.moc"

Upvotes: 2

Related Questions