#include <QtGui>
#include <cmath>
#include <limits>
using namespace std;
{
Q_OBJECT
public:
, m_piecesCount(0) {
for (int i = 0; i < 100; ++i)
m_colors <<
QColor(qrand
() % 256, qrand
() % 256, qrand
() % 256);
}
protected:
Q_UNUSED(e);
opt.init(this);
p.
setRenderHints(QPainter::Antialiasing);
p.translate(0.5, 0.5);
style
()->drawPrimitive
(QStyle::PE_Widget,
&opt,
&p,
this);
QRectF container
= contentsRect
();
container.adjust(container.width() * 0.25,
container.height() * 0.25,
container.width() * -0.25,
container.height() * -0.25);
p.setPen(Qt::black);
p.drawRect(container);
const qreal spacing = 3;
container.adjust(spacing, spacing, -spacing, -spacing);
p.
setPen(QPen(Qt
::black,
1, Qt
::DashLine));
if (container.width() < 1 || container.height() < 1)
return;
qreal side = squareSide(container, m_piecesCount);
int rows = container.height() / side;
int cols = container.width() / side;
emit infoChanged
(QString("Rows: %1\tCols: %2").
arg(rows
).
arg(cols
));
for (int i = 0; i < m_piecesCount; ++i) {
int r = i / cols;
int c = i % cols;
QRectF square
(container.
left() + c
* side, container.
top() + r
* side, side, side
);
if (i < m_colors.size())
p.setBrush(m_colors.at(i)); // just to make sure ;)
p.drawRect(square);
if (side > 14) // don't draw text if square is too small
p.
drawText(square, Qt
::AlignCenter,
QString::number(i
));
}
}
public slots:
void setPiecesCount(int count) {
m_piecesCount = count;
update();
}
signals:
void infoChanged(const QString&);
private:
int m_piecesCount;
QList<QColor> m_colors;
// The function that needs to be improved!!!
qreal squareSide(const QRectF& r, int piecesCount) {
const qreal w = r.width();
const qreal h = r.height();
qreal top = qMin(w, h);
qreal bottom = 1;
while (top - bottom > 0.01) {
qreal mid = bottom + (top - bottom) / 2;
if (floor(w / mid) * floor(h / mid) < piecesCount)
top = mid;
else
bottom = mid;
}
return bottom;
}
};
{
Q_OBJECT
public:
m_widget = new Widget;
connect(m_widget, SIGNAL(infoChanged(const QString&)), this, SLOT(updateStatusBar(const QString&)));
connect(m_spinBox, SIGNAL(valueChanged(int)), m_widget, SLOT(setPiecesCount(int)));
m_spinBox->setRange(1, 100);
m_spinBox->setValue(5);
cw->setLayout(lo);
lo->addWidget(m_widget);
lo->addWidget(m_spinBox);
setCentralWidget(cw);
statusBar()->addPermanentWidget(m_infoLabel);
}
public slots:
void updateStatusBar(const QString& info) {
m_infoLabel->setText(info);
}
private:
Widget* m_widget;
};
int main(int argc, char** argv)
{
MainWindow mw;
qsrand
(QTime::currentTime().
msec());
mw.show();
return app.exec();
}
#include "main.moc"
#include <QtGui>
#include <cmath>
#include <limits>
using namespace std;
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget* parent = 0)
: QWidget(parent)
, m_piecesCount(0) {
for (int i = 0; i < 100; ++i)
m_colors << QColor(qrand() % 256, qrand() % 256, qrand() % 256);
}
protected:
void paintEvent(QPaintEvent* e) {
Q_UNUSED(e);
QStyleOption opt;
opt.init(this);
QPainter p(this);
p.setRenderHints(QPainter::Antialiasing);
p.translate(0.5, 0.5);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
QRectF container = contentsRect();
container.adjust(container.width() * 0.25,
container.height() * 0.25,
container.width() * -0.25,
container.height() * -0.25);
p.setPen(Qt::black);
p.drawRect(container);
const qreal spacing = 3;
container.adjust(spacing, spacing, -spacing, -spacing);
p.setPen(QPen(Qt::black, 1, Qt::DashLine));
if (container.width() < 1 || container.height() < 1)
return;
qreal side = squareSide(container, m_piecesCount);
int rows = container.height() / side;
int cols = container.width() / side;
emit infoChanged(QString("Rows: %1\tCols: %2").arg(rows).arg(cols));
for (int i = 0; i < m_piecesCount; ++i) {
int r = i / cols;
int c = i % cols;
QRectF square(container.left() + c * side, container.top() + r * side, side, side);
if (i < m_colors.size())
p.setBrush(m_colors.at(i)); // just to make sure ;)
p.drawRect(square);
if (side > 14) // don't draw text if square is too small
p.drawText(square, Qt::AlignCenter, QString::number(i));
}
}
public slots:
void setPiecesCount(int count) {
m_piecesCount = count;
update();
}
signals:
void infoChanged(const QString&);
private:
int m_piecesCount;
QList<QColor> m_colors;
// The function that needs to be improved!!!
qreal squareSide(const QRectF& r, int piecesCount) {
const qreal w = r.width();
const qreal h = r.height();
qreal top = qMin(w, h);
qreal bottom = 1;
while (top - bottom > 0.01) {
qreal mid = bottom + (top - bottom) / 2;
if (floor(w / mid) * floor(h / mid) < piecesCount)
top = mid;
else
bottom = mid;
}
return bottom;
}
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget* parent = 0) : QMainWindow(parent) {
m_widget = new Widget;
connect(m_widget, SIGNAL(infoChanged(const QString&)), this, SLOT(updateStatusBar(const QString&)));
m_spinBox = new QSpinBox;
connect(m_spinBox, SIGNAL(valueChanged(int)), m_widget, SLOT(setPiecesCount(int)));
m_spinBox->setRange(1, 100);
m_spinBox->setValue(5);
QWidget* cw = new QWidget;
QVBoxLayout* lo = new QVBoxLayout;
cw->setLayout(lo);
lo->addWidget(m_widget);
lo->addWidget(m_spinBox);
setCentralWidget(cw);
m_infoLabel = new QLabel;
statusBar()->addPermanentWidget(m_infoLabel);
}
public slots:
void updateStatusBar(const QString& info) {
m_infoLabel->setText(info);
}
private:
QLabel* m_infoLabel;
QSpinBox* m_spinBox;
Widget* m_widget;
};
int main(int argc, char** argv)
{
QApplication app(argc, argv);
MainWindow mw;
qsrand(QTime::currentTime().msec());
mw.show();
return app.exec();
}
#include "main.moc"
To copy to clipboard, switch view to plain text mode
Bookmarks