QT点击菜单生成滚动日志窗口

文章目录

    • 一、点击菜单栏生成新的窗口
    • 二、实现窗口间的通信

最终实现的效果是:通过点击菜单栏打开一个日志窗口,日志窗口可以不断接收信息,并自动滚动下拉至末尾显示。

一、点击菜单栏生成新的窗口

直接上操作。
1.生成新的窗口
QT点击菜单生成滚动日志窗口_第1张图片
QT点击菜单生成滚动日志窗口_第2张图片
QT点击菜单生成滚动日志窗口_第3张图片
2.在主窗口中声明子窗口
主窗口头文件中,引用子窗口的头文件,并声明成员变量
QT点击菜单生成滚动日志窗口_第4张图片

3.主窗口的操作
菜单栏设定内容
QT点击菜单生成滚动日志窗口_第5张图片
添加槽 选择trigger
QT点击菜单生成滚动日志窗口_第6张图片
QT点击菜单生成滚动日志窗口_第7张图片
添加代码
QT点击菜单生成滚动日志窗口_第8张图片

if(myDialogWindow==nullptr)
{
    myDialogWindow=new DialogWindow(this); //实例化子窗口,并指定父窗口
    myDialogWindow->setModel(false); //设置为非模态,即用户打开该窗口时,仍可以与其他窗口进行交互
    myDialogWindow->show();
}
else 
{
    myDialogWindow->show();//若已实例化过就直接打开
}

此时就已经能通过打开子窗口了

4.日志窗口的设置
添加一个textBrowser控件,设定一个喜欢的名字
在这里插入图片描述
5.可能存在的问题
在这里插入图片描述
会提示无法解析的外部符号"public:__Dialog::Dialog(class QWidget*)"
这个问题产生的原因是构建时没有为子窗口自动生成新的ui_xx.h文件
在这里插入图片描述
经测试似乎构建时候不选择shadow build就容易出现这个bug。且即使shadow build了,若shadow目录是在工程目录(cpp文件所在目录)下,也可能出现这个问题。
在这里插入图片描述

二、实现窗口间的通信

有两种方法。分别利用传参和信息槽。
一、传参
由于我们是父窗口向子窗口发日志数据,所以可以通过修改子窗口类的构造函数,从而在实例化时实现传参。
但这个方法不太好看,而且可能会有后续的问题,所以就简单说一下,不多补充。

public:
    explicit DialogWindow(QWidget *parent = nullptr,QString receiveData=NULL);
    ~DialogWindow();

二、信息槽
1.子窗口的操作
在子窗口头文件中声明接收信息的方法。
QT点击菜单生成滚动日志窗口_第9张图片

private slots:
    void receiveData(QString data); //槽函数

在cpp文件中实例化,即接收信息后,将信息打印在textBroser中
QT点击菜单生成滚动日志窗口_第10张图片

void dialogwindow::receiveData(QString data)
{
    ui->dialogTextBrowser->textCursor().insertText(data);
    ui->dialogTextBrowser->textCursor().insertText("\n");
}

回到子窗口的ui设计界面,右键textBrowser添加一个textChanged的槽
QT点击菜单生成滚动日志窗口_第11张图片
并添加如下代码,使得每次dialog更新后,都让光标指向文本最后,即可实现日志自动下拉滚动。

void DialogWindow::on_dialogTextBrowser_textChanged()
{
    ui->dialogTextBrowser->moveCursor(QTextCursor::End);
}

2.主窗口的操作
在主窗口头文件中声明发送信息的信号的方法,该方法不需要实例化。
QT点击菜单生成滚动日志窗口_第12张图片

signals: void sendData(QString); //信号函数

最后建立连接。
我这里是在实例化子窗口时,建立了连接。
建立完连接后,就可以随时通过信号函数发送信息。
我这里测试是在,已经实例化窗口后,再按打开窗口的按钮,就发送一条信息。
QT点击菜单生成滚动日志窗口_第13张图片

void MainWindow::on_actionOpenDialog_triggered()
{
    if(myDialogWindow==nullptr)
    {
        myDialogWindow=new DialogWindow(this); //实例化子窗口,并指定父窗口
        myDialogWindow->setModel(false); //设置为非模态,即用户打开该窗口时,仍可以与其他窗口进行交互
        connect(this,SIGNAL(sendData(QString)),myDialogWindow,SLOT(receiveData(QString))); //建立连接
        myDialogWindow->show();
    }
    else
    {
        myDialogWindow->show();//若已实例化过就直接打开
        sendData("已经实例化过"); //若已实例化过,就给日志文件做记录,即给子窗口发送信息
    }
}

—————————————————————————————————————————————
如果这篇文章对你有帮助,欢迎在评论区告诉我。
你们的支持是我更新的动力。
当然有任何问题也可随时与我联系。

你可能感兴趣的:(QT,Qt,Qt入门,Qt5,类)