简体   繁体   English

QT - 使用MainWIndow Parent的Designer Form Widget中的QPushButton无法单击

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

I've got a problem with Qt. 我有Qt的问题。

TL;DR TL; DR

My designer form class inherits from QWidget and contains a pushbutton. 我的设计器表单类继承自QWidget并包含一个按钮。 I construct an object from this class with a parent parameter, which is a MainWindow object. 我使用父参数从此类构造一个对象,该参数是一个MainWindow对象。 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. 显示小部件,但无法单击该按钮,不会对鼠标悬停做出反应,但是当使用Tab键突出显示按钮并按下空格时会触发类似onclick的事件。


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::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. todoWidget是MainWindow类的私有成员。 I understand, that if a parent is given in the constructor of a QWidget, the widget is drawn inside the parent. 我理解,如果在QWidget的构造函数中给出了父级,则该小部件将在父级内部绘制。 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. 如果我按Tab键直到它在焦点上而不是按空格键,我就能触发像onclick这样的东西,但它对鼠标悬停也没有反应。 The TodoWidget class is a Designer Form Class, and right now I simplified it to have only 1 element, the pushbutton. TodoWidget类是一个Designer Form类,现在我把它简化为只有一个元素,即按钮。 Here is the TodoWidget source: 这是TodoWidget源:

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. t是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). 我不认为有必要显示代码,因为它应该与GUI无关,因为它是一个共享库(我用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. mainWindow以中央widget widgetareas,状态栏,菜单栏等形式预定义了布局。因此,任何一个widget都需要设置到这些区域才能正常工作。 Try setting your dialog with call mainWindow.setcentralwidget(todowidget). 尝试使用调用mainWindow.setcentralwidget(todowidget)设置对话框。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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