开发者

Qt - reloading widget contents

I'm trying to modify the fridge magnets example by adding a button that will reload the widget where the draggable labels are drawn, reflecting any changes made to the text file it reads. I defined another class that would contain the button and the DragWidget object, so there would be an instance of this class instead of DragWidget in main():

class wrapWidget: public QWidget
{
    Q_OBJECT
public:
    wrapWidget();

};

wrapWidget::wrapWidget()
{
    QGridLayout *gridlayout = new QGridLayout();
    DragWidget *w = new DragWidget();
    QPushButton *b = new开发者_如何学Go QPushButton("refresh");
    gridlayout ->addWidget(w,0,0);
    gridlayout ->addWidget(b,1,0);
    setLayout(gridlayout );

    connect(b,SIGNAL(clicked()),w,SLOT(draw()));
}

The call to connect is where I'm trying to do the refresh thing. In the original fridge magnets example, all the label drawing code was inside the constructor of the DragWidget class. I moved that code to a public method that I named 'draw()', and called this method from the constructor instead. Here's DragWidget definition and implementation:

#include <QWidget>

QT_BEGIN_NAMESPACE
class QDragEnterEvent;
class QDropEvent;
QT_END_NAMESPACE

class DragWidget : public QWidget
{
public:
    DragWidget(QWidget *parent = 0);

public slots:
    void draw();

protected:
    void dragEnterEvent(QDragEnterEvent *event);
    void dragMoveEvent(QDragMoveEvent *event);
    void dropEvent(QDropEvent *event);
    void mousePressEvent(QMouseEvent *event);
    void paintEvent(QPaintEvent *event);
};

DragWidget::DragWidget(QWidget *parent)
    : QWidget(parent)
{

    draw();

    QPalette newPalette = palette();
    newPalette.setColor(QPalette::Window, Qt::white);
    setPalette(newPalette);

    setMinimumSize(400, 100);//qMax(200, y));
    setWindowTitle(tr("Fridge Magnets"));
    setAcceptDrops(true);
}

void DragWidget::draw(){
    QFile dictionaryFile(":/dictionary/words.txt");
    dictionaryFile.open(QFile::ReadOnly);
    QTextStream inputStream(&dictionaryFile);

    int x = 5;
    int y = 5;

    while (!inputStream.atEnd()) {
        QString word;
        inputStream >> word;
        if (!word.isEmpty()) {
            DragLabel *wordLabel = new DragLabel(word, this);
            wordLabel->move(x, y);
            wordLabel->show();
            wordLabel->setAttribute(Qt::WA_DeleteOnClose);
            x += wordLabel->width() + 2;
            if (x >= 245) {
                x = 5;
                y += wordLabel->height() + 2;
            }
        }
    }
}

I thought that maybe calling draw() as a slot would be enough to reload the labels, but it didn't work. Putting the draw() call inside the widget's overriden paintEvent() instead of the constructor didn't work out as well, the program would end up in an infinite loop.

What I did was obviously not the right way of doing it, so what should I be doing instead?


My quick guess is, you haven't added Q_OBJECT macro to dragwidget.h header, the moc file for DragWidget class wasn't generated and the connect failed with "no such slot as draw()" error.

It might be also a good idea to add "CONFIG += console" to .pro file - you'll see all warning messages (like the one about connect error), so tracking such mistakes would be easier. You might also check return value of connect.


I noticed that you opened file this way:

QFile dictionaryFile(":/dictionary/words.txt");

Note that the file name starts with ":", and it means that the file will be read from your qrc resource package instead of your local disk. So if you made the change on words.txt, it will be read by code only when you compiled qrc file next time. So you must have understood how to fix it, right? Good Luck:)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜