简体   繁体   中英

QT - QPushButton in Designer Form Class Widget with MainWIndow Parent can't be clicked

I've got a problem with Qt.

TL;DR

My designer form class inherits from QWidget and contains a pushbutton. I construct an object from this class with a parent parameter, which is a MainWindow object. The widget is shown, but the button can't be clicked, doesn't react to mouse hover, but an onclick-like event is triggered when the button is highlighted with tab key and space is pressed.


Here is my main function:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow *w;
    if(argc == 2)
    {
        w = new MainWindow(argv[1]);
    }
    else
    {
        w = new MainWindow();
    }

    w->show();

    return a.exec();
}

Here is the source of MainWindow:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow (parent),
    ui(new Ui::MainWindow),
    todoWidget(nullptr)
{
    ui->setupUi(this);
    todoWidget = new TodoWidget(nullptr, this);
    todoWidget->setEnabled(true);
}

MainWindow::MainWindow(const char *saveFilePath, QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    todoWidget(new TodoWidget(saveFilePath, this))
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
    delete todoWidget;
}

todoWidget is a private member of MainWindow class. I understand, that if a parent is given in the constructor of a QWidget, the widget is drawn inside the parent. That happens BUT the button in the widget is not clickable. I'm able to trigger something like an onclick if I press tab until it's in focus than press space, but it doesn't react even to mouse hover. The TodoWidget class is a Designer Form Class, and right now I simplified it to have only 1 element, the pushbutton. Here is the TodoWidget source:

TodoWidget::TodoWidget(const char *path, QWidget *parent) :
    QWidget (parent),
    t (nullptr),
    ui(new Ui::TodoWidget)
{
    ui->setupUi(this);
    if(!path)
    {
        path = "./tasks/taks";
    }
    open(path);
    makeConnections();
    todoModel = new TaskListModel(t->tasksWithStatus(Task::Status::TODO), this);
    inProgressModel = new TaskListModel(t->tasksWithStatus(Task::Status::IN_PROGRESS), this);
    finishedModel = new TaskListModel(t->tasksWithStatus(Task::Status::FINISHED), this);
//  ui->todoView->setModel(todoModel);
//  ui->inProgressView->setModel(inProgressModel);
//  ui->finishedView->setModel(finishedModel);
}

TodoWidget::~TodoWidget()
{
    delete t;
    delete ui;
}

void TodoWidget::open(const char *path)
{
    if(validateSaveFile(path))
    {
        delete t;
        t = new todo(path, this);
        this->path = path;
    }
}

void TodoWidget::progressTask(unsigned int index)
{
    t->progressTask(index);
}

void TodoWidget::displaySuccess(const QString &msg)
{
    QMessageBox::information(this, "Success", msg);
}

void TodoWidget::displayError(const QString &errMsg)
{
    QMessageBox::critical(this, "Error", errMsg);
}

void TodoWidget::changeProject(const char *path)
{
    open(path);
}

void TodoWidget::addButtonClicked()
{
    AddWindow *addWindow = new AddWindow(this);
    connect(addWindow, &AddWindow::addTask, [this](const QString &args)->void{addTask(args);});
    addWindow->show();
}

bool TodoWidget::validateSaveFile(const QString &path)
{
    /*
     * C:/ and (wordchar 0 or more times/) 0 or more times
     * ./ and (wordchar 0 or more times/) 0 or more times
     * / and (wordchar 0 or more times/) 0 or more times
     * (wordchar 0 or more times/) 0 or more times
     *
     * Note: the parentheses are not present in the regexp
     * Note: wordchar is any character which might be part of a word (alfanum and _ I think)
     */
    QRegularExpression regexp("([a-zA-Z]:/|[.]{0,2}/)?((.*)/)*");
    QRegularExpressionMatch match = regexp.match(path);

    if(!match.hasMatch())
    {
        emit someError("Not a valid file");
        return false;
    }
    else
    {
        QDir sp(match.captured(0));
        if(!sp.exists())
        {
            sp.mkpath(".");
        }
    }
    QFile file(path);
    if(!file.open(QIODevice::Append | QIODevice::Text))
    {
        emit someError(QString("Can't open file") + file.errorString());
        return false;
    }
    return true;
}

void TodoWidget::makeConnections()
{
    connect(t, &todo::taskAdded, this, &TodoWidget::displaySuccess);
    connect(t, &todo::taskNotAdded, this, &TodoWidget::displayError);
    connect(t, &todo::taskMadeProgress, this, &TodoWidget::displaySuccess);
    connect(t, &todo::noProgress, this, &TodoWidget::displayError);
    connect(t, &todo::saved, this, &TodoWidget::displaySuccess);
    connect(t, &todo::notSaved, this, &TodoWidget::displayError);
    connect(this, &TodoWidget::addTask, t, &todo::addTask);
    connect(this, &TodoWidget::someError, this, &TodoWidget::displayError);
    connect(this->ui->addButton, &QPushButton::clicked, this, &TodoWidget::addButtonClicked);
}

void TodoWidget::modelStuff()
{

}

The t is a private member of TodoWidget. The type is todo. I don't think it's necessary to show the code, because it should have nothing to do with the GUI, because it's a shared library (which I created with Qt).

I've tried several things now, I can't even remember them all, but none worked. I'll appreciate any help. Thanks

The mainWindow has predefined layout in form of central widget dockareas, status bar ,menu bar etc.So any of the widget need to be set into those areas for working properly. Try setting your dialog with call mainWindow.setcentralwidget(todowidget).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM