首页 Qt 学习之路 2 Qt 学习之路 2(17):文件对话框

Qt 学习之路 2(17):文件对话框

98 7.9K

在前面的章节中,我们讨论了 Qt 标准对话框QMessageBox的使用。所谓标准对话框,其实也就是一个普通的对话框。因此,我们同样可以将QDialog所提供的其它特性应用到这种标准对话框上面。今天,我们继续讨论另外一个标准对话框:QFileDialog,也就是文件对话框。在本节中,我们将尝试编写一个简单的文本文件编辑器,我们将使用QFileDialog来打开一个文本文件,并将修改过的文件保存到硬盘。这或许是我们在本系列中所提供的第一个带有实际功能的实例。

首先,我们需要创建一个带有文本编辑功能的窗口。借用我们前面的程序代码,应该可以很方便地完成:

openAction = new QAction(QIcon(":/images/file-open"), tr("&Open..."), this);
openAction->setShortcuts(QKeySequence::Open);
openAction->setStatusTip(tr("Open an existing file"));

saveAction = new QAction(QIcon(":/images/file-save"), tr("&Save..."), this);
saveAction->setShortcuts(QKeySequence::Save);
saveAction->setStatusTip(tr("Save a new file"));

QMenu *file = menuBar()->addMenu(tr("&File"));
file->addAction(openAction);
file->addAction(saveAction);

QToolBar *toolBar = addToolBar(tr("&File"));
toolBar->addAction(openAction);
toolBar->addAction(saveAction);

textEdit = new QTextEdit(this);
setCentralWidget(textEdit);

我们在菜单和工具栏添加了两个动作:打开和保存。接下来是一个QTextEdit类,这个类用于显示富文本文件。也就是说,它不仅仅用于显示文本,还可以显示图片、表格等等。不过,我们现在只用它显示纯文本文件。QMainWindow有一个setCentralWidget()函数,可以将一个组件作为窗口的中心组件,放在窗口中央显示区。显然,在一个文本编辑器中,文本编辑区就是这个中心组件,因此我们将QTextEdit作为这种组件。

我们使用connect()函数,为这两个QAction对象添加响应的动作:

/// !!!Qt5
connect(openAction, &QAction::triggered, this, &MainWindow::openFile);
connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile);

/// !!!Qt4
connect(openAction, SIGNAL(triggered()), this, SLOT(openFile()));
connect(saveAction, SIGNAL(triggered()), this, SLOT(saveFile()));

这些应该都不是问题。我们应该能够很清楚这些代码的含义。下面是最主要的openFile()saveFile()这两个函数的代码:

void MainWindow::openFile()
{
    QString path = QFileDialog::getOpenFileName(this,
                                                tr("Open File"),
                                                ".",
                                                tr("Text Files(*.txt)"));
    if(!path.isEmpty()) {
        QFile file(path);
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            QMessageBox::warning(this, tr("Read File"),
                                 tr("Cannot open file:\n%1").arg(path));
            return;
        }
        QTextStream in(&file);
        textEdit->setText(in.readAll());
        file.close();
    } else {
        QMessageBox::warning(this, tr("Path"),
                             tr("You did not select any file."));
    }
}

void MainWindow::saveFile()
{
    QString path = QFileDialog::getSaveFileName(this,
                                                tr("Open File"),
                                                ".",
                                                tr("Text Files(*.txt)"));
    if(!path.isEmpty()) {
        QFile file(path);
        if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
            QMessageBox::warning(this, tr("Write File"),
                                       tr("Cannot open file:\n%1").arg(path));
            return;
        }
        QTextStream out(&file);
        out << textEdit->toPlainText();
        file.close();
    } else {
        QMessageBox::warning(this, tr("Path"),
                             tr("You did not select any file."));
    }
}

openFile()函数中,我们使用QFileDialog::getOpenFileName()来获取需要打开的文件的路径。这个函数具有一个长长的签名:

QString getOpenFileName(QWidget * parent = 0,
                        const QString & caption = QString(),
                        const QString & dir = QString(),
                        const QString & filter = QString(),
                        QString * selectedFilter = 0,
                        Options options = 0)

不过注意,它的所有参数都是可选的,因此在一定程度上说,这个函数也是简单的。这六个参数分别是:

  • parent:父窗口。我们前面介绍过,Qt 的标准对话框提供静态函数,用于返回一个模态对话框(在一定程度上这就是外观模式的一种体现);
  • caption:对话框标题;
  • dir:对话框打开时的默认目录,“.” 代表程序运行目录,“/” 代表当前盘符的根目录(特指 Windows 平台;Linux 平台当然就是根目录),这个参数也可以是平台相关的,比如“C:\\”等;
  • filter:过滤器。我们使用文件对话框可以浏览很多类型的文件,但是,很多时候我们仅希望打开特定类型的文件。比如,文本编辑器希望打开文本文件,图片浏览器希望打开图片文件。过滤器就是用于过滤特定的后缀名。如果我们使用“Image Files(*.jpg *.png)”,则只能显示后缀名是 jpg 或者 png 的文件。如果需要多个过滤器,使用“;;”分割,比如“JPEG Files(*.jpg);;PNG Files(*.png)”;
  • selectedFilter:默认选择的过滤器;
  • options:对话框的一些参数设定,比如只显示文件夹等等,它的取值是enum QFileDialog::Option,每个选项可以使用 | 运算组合起来。

QFileDialog::getOpenFileName()返回值是选择的文件路径。我们将其赋值给 path。通过判断 path 是否为空,可以确定用户是否选择了某一文件。只有当用户选择了一个文件时,我们才执行下面的操作。在saveFile()中使用的QFileDialog::getSaveFileName()也是类似的。使用这种静态函数,在 Windows、Mac OS 上面都是直接调用本地对话框,但是 Linux 上则是QFileDialog自己的模拟。这暗示了,如果你不使用这些静态函数,而是直接使用QFileDialog进行设置,就像我们前面介绍的 QMessageBox 的设置一样,那么得到的对话框很可能与系统对话框的外观不一致。这一点是需要注意的。

首先,我们创建一个QFile对象,将用户选择的文件路径传递给这个对象。然后我们需要打开这个文件,使用的是QFile::open(),其参数是指定的打开方式,这里我们使用只读方式和文本方式打开这个文件(因为我们选择的是后缀名 txt 的文件,可以认为是文本文件。当然,在实际应用中,可能需要进行进一步的判断)。QFile::open()打开成功则返回 true,由此继续进行下面的操作:使用QTextStream::readAll()读取文件所有内容,然后将其赋值给QTextEdit显示出来。最后不要忘记关闭文件。另外,saveFile()函数也是类似的,只不过最后一步,我们使用<<重定向,将QTextEdit的内容输出到一个文件中。关于文件操作,我们会在后面的章节中进一步介绍。

这里需要注意一点:我们的代码仅仅是用于演示,很多必须的操作并没有进行。比如,我们没有检查这个文件的实际类型是不是一个文本文件。并且,我们使用了QTextStream::readAll()直接读取文件所有内容,如果这个文件有 100M,程序会立刻死掉,这些都是实际程序必须考虑的问题。不过这些内容已经超出我们本章的介绍,也就不再详细说明。

至此,我们的代码已经介绍完毕,马上可以编译运行一下了:

QFileDialog on KDE

本章的代码可以在这里下载:

98 评论

adfae 2012年11月25日 - 00:39

大哥,我还是没法编译,卡在编译资源的时候. 4.8.3, win32

mingw32-make[1]: Leaving directory `D:/Documents and Settings/lulu/qttest/QtStudyRoad-build-Unnamed_gcc-Debug'
process_begin: CreateProcess(NULL, bin\rcc.exe -name resource ..\src\resource.qrc -o debug\qrc_resource.cpp, ...) failed.
make (e=2): 系统找不到指定的文件。
mingw32-make[1]: *** [debug/qrc_resource.cpp] Error 2
mingw32-make: *** [debug] Error 2
00:30:21: 进程"C:\MinGW\bin\mingw32-make.exe"退出,退出代码 2 。
Error while building/deploying project QtStudyRoad (target: Unnamed_gcc)
When executing step 'Make'

debug\qrc_resource.cpp这个文件似乎没有被生成出来

回复
adfae 2012年11月25日 - 00:57

qt库的bug,己解决

回复
DevBean 2012年11月25日 - 10:02

Qt 库的 bug?怎么解决的呀?

回复
aaaa 2013年1月15日 - 07:52

😛 我觉得是他的路径里面有空格或者中文什么的导致的

回复
豆子 2013年1月15日 - 11:18

这个不大清楚了,呵呵

gavin 2013年1月27日 - 11:50

一个小问题,窗口忘记加statusBar了 😛

回复
豆子 2013年1月27日 - 21:21

只是无伤大雅的 ;-P 因为程序中实际是用不到这一项的。

回复
豆门之耻啊! 2013年4月4日 - 14:00

豆子,请问qt creator有没有和eclipse一样自动添加需要的头文件的功能?

回复
豆子 2013年4月7日 - 09:32

目前好像没有类似的功能,并且一般也不大容易实现类似的功能:因为 Java 文件名和类名是一致的,但是 C++ 没有此要求,如果要实现类似的功能,必须扫描全部文件来找到这个类。

回复
Jakes 2013年4月27日 - 16:59

程序读取文本时中文出现问题。
如过我读入的是utf8的文本,中文没问题。如果是ANSI文本,中文乱码。

回复
Jakes 2013年4月27日 - 17:58

发现了,如果使用QTextStream类,中文就不会出现乱码。这是为什么?

回复
豆子 2013年4月28日 - 09:06

QTextStream 在内部统一使用 Unicode 编码,所以用 QTextStream 写入和读取都不会有乱码。

回复
豆子 2013年4月28日 - 09:02

应该是编码问题,ANSI 在中文环境下使用的是 GB2312 编码,你必须将 ANSI 文件以 GB2312 解码后才能正常读取(如果没有明确指定的话,默认读取是按照 ASCII 解码的,所以会出现乱码)。

回复
Jakes 2013年4月28日 - 13:01

现在又产生了一个疑问。对于UTF-8编码,区分有BOM和无BOM之分,但QT保存的文本默认是无BOM的。如何判断文件编码,选择性的设置编码类型呢?

回复
豆子 2013年4月28日 - 15:39

判断文件编码没有很好的办法,一般是用某些算法去检测一段字符,来“猜测”是哪个编码。如果要自己去写类似的算法,你必须了解所有编码的格式,这在实际开发中往往是不可行的。因此类似的需求会使用某些成熟的第三方库,比如 Mozilla 提供的 chardet(http://www-archive.mozilla.org/projects/intl/chardet.html)等。

回复
Jakes 2013年4月28日 - 17:07

嗯,学习了。

回复
Zeck 2013年5月15日 - 11:04

希望豆子能弄几个界面的类的详细解说 像QWidget 和QDialog等 有些布局之类是不能用的 新手难知道。。还有QMenuBar等效果也不一样 😯

回复
豆子 2013年5月15日 - 13:03

哪些布局不能使用的?这个不大清楚啊

回复
junekai 2013年9月3日 - 10:46

豆子,我按照你的教程写的报了一堆错,首先,saveAction没有高亮,而且报错:saveAction' was not declared in this scope
是不是要加什么头文件啊?openAction是可以的..

textEdit也是同样的错误,was not declared in this scope,我添加了QTextEdit头文件..

void MainWindow::openFile()和saveFile()报同样的错:no 'void MainWindow::openFile()' member function declared in class 'MainWindow'

还有一个错误是我按照以前你说的写:
connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile);
这样会报错,但是我看帮助文件改成了:
connect(saveAction,SIGNAL(triggered()), this, SLOT(saveFile()));
就没有报错了,为什么会这样啊?

不好意思啊,问题有点多...

回复
豆子 2013年9月4日 - 08:56

saveAction、textEdit 和 openFile() 是因为你没有在头文件中声明。这是 C++ 所要求的,所有变量在使用之前必须声明。至于 connect() 这段,是因为这是 Qt5 的新语法,如果你使用的不是 Qt5,就需要改成 Qt4 的语法,也就是带有 SIGNAL/SLOT 宏的那种。

回复
肖磊 2016年5月24日 - 23:18

我的是QT5.5版本,为啥我的connect(saveAction, &QAction::triggered, this, &MainWindow::saveFile);
这样会报错,但是我看帮助文件改成了:
connect(saveAction,SIGNAL(triggered()), this, SLOT(saveFile()));
就没有报错了,为什么会这样啊?和上面一个情况!!!

回复
豆子 2016年5月26日 - 22:03

有没有在 .pro 文件添加 CONFIG += c++11

回复
小胖子 2013年10月8日 - 19:42

QMenu *file = menuBar()->addMenu(tr("&File"));
file->addAction(openAction);
file->addAction(saveAction);

QToolBar *toolBar=addToolBar("&File");
toolBar->addAction(openAction);
toolBar->addAction(saveAction);

豆子 我的菜单怎么不显示啊,那个toolbar显示呢
不知道什么情况谢谢

回复
小胖子 2013年10月8日 - 20:18

我发现了 原来是因为我建立 的工程里面有// ui->setupUi(this);
这一句 哈哈 去掉就ok

回复
2013年12月10日 - 21:06

你好,我测试了一下您上传的“ch17-qt5.zip”代码,结果出现许多错误。根据错误信息,我在“mainwindow.cpp”中加入

#include
#include
#include
#include
#include
#include

于是程序可以通过编译,正常运行了。

我想知道我是不是弄错了什么地方。我没有使用"Qt Creator",是手动调用qmake、make等命令编译的。(.pro文件要作修改,加上”QT += widgets“)莫非使用"Qt Creator"就不需要亲自include上面的那些文件?抑或豆子忘记添加了?对这里不太清楚~

回复
2013年12月10日 - 21:08

天啊,include被吞掉了!!!

QAction

QMenuBar

QToolBar

QTextEdit

QFileDialog

QMessageBox

就是这几个。

回复
豆子 2013年12月10日 - 22:42

如果需要<和>,请使用&lt;和&gt;转义

回复
bingo 2013年12月25日 - 16:19

好给力呀,跟着豆子学,现在都水写记事本了。今天学到地十七课。留个脚印。

回复
大灰狼嘎嘎 2014年1月27日 - 18:01

打开文件那一段代码,能不能用 try...catch...改写?
Qt提供了相关的异常捕获类吗?

回复
豆子 2014年1月27日 - 19:17

Qt 基本不使用任何异常代码。因为 Qt 在开始开发时,异常还不被所有 Qt 所需要的编译器支持。所以,今天为了保持 API 兼容性,旧的模块也不能增加异常的代码。但是新的模块可能会增加。简答来说,Qt 现在还是很有限地使用异常:http://qt-project.org/doc/qt-5.0/qtdoc/exceptionsafety.html

回复
green 2014年3月4日 - 15:30

hello,我最近在做ATM机的实验。在做的过程中遇到了难题(申明一下,我是一个QT新手):
我是将用户信息保存在一个txt文件中的,是卡号、密码、余额各一行这样三个一循环。
在取款时,同时必须将txt文件中某账户的余额也改变。可是我不知道怎样将游标指向txt文件中的特定行,并将它用新的余额覆盖。很急哦。。。求大神指点,现在这里谢谢了!

回复
豆子 2014年3月5日 - 09:59

ATM 用 txt 存密码岂不是太不安全?建议改成数据库,这样就方便很多了。如果一定要 txt,那就一行一行地遍历找到那行数据然后修改吧。

回复
zhongshengzhou 2014年3月27日 - 21:03

您好 最近在学习使用QT5 这里的讲得很好 在使用示例代码使用文件对话框时 为什么只能选择一次文件 再次选择文件的时候显示You did not select any file的消息框 然后保存文件对话框也是没反映的 请问该如何解决 感谢

回复
豆子 2014年3月28日 - 09:49

我这里测试是正常的,不知道哪里出了问题?

回复
zhongshengzhou 2014年3月28日 - 11:01

我用的vs2010 是不是和设置有关呢?另外我还加入了opencv,qT应该是兼容的?

回复
zhongshengzhou 2014年3月28日 - 11:15

我把opencv去掉后 就正常了 纠结 和MFC一样又是兼容性问题
请问您有没有试过QT和opencv同时使用?有解决的办法不?

回复
豆子 2014年3月28日 - 11:25

没有相关经验。不过不清楚 opencv 怎么会影响到 Qt 的代码?这段代码非常简单,看上去不大会出错的。

回复
zhongshengzhou 2014年3月28日 - 11:36

我现在尝试把opencv重新编译成QT兼容的

zhongshengzhou 2014年3月28日 - 14:40

问题已经解决,我把opencv用Cmake重新编译成QT版的,然后在QT Creater上运行无问题。

豆子 2014年3月28日 - 20:38

看来还是冲突了。一般版本不对都会不能通过编译或者运行时直接出错,像你这种运行正常、只是有小问题的还没见过。

静花水跃 2014年4月23日 - 19:32

必须一定要赞扬豆子了,谢谢你的精力,时间免费无偿的默默地服务于人们,真好

回复
豆子 2014年4月25日 - 09:13

多谢支持!

回复
白菜 2014年7月22日 - 14:38

豆子你好,请问在源码mainwindow.h里的class QtextEdit;
这句话是干什么用的? 另外为什么会有一个private.slot,

回复
豆子 2014年7月25日 - 23:24

class QtextEdit; 是前置声明,这是基础 C++ 的语法,建议看看相关教程。private slot 是私有槽函数,可以认为是一种能够与信号连接的私有函数。

回复
bryant 2014年10月1日 - 21:04

那为何QAction不用类前置声明呢?
看到这里有些不解,希望能够解惑

回复
豆子 2014年10月2日 - 20:11

头文件中可以使用前置声明,但是如果在源代码文件中,因为需要使用这个类的函数,所以比如完全 include 进来

回复
连皓 2014年12月22日 - 22:08

不加slot可以吗?我记得你之前说slot函数可以看做普通的member函数

豆子 2014年12月22日 - 22:15

如果是 Qt 5,使用新语法可以连接到任意函数;对于 Qt 4 则不可以。“slot函数可以看做普通的member函数”的含义是在进行普通的函数调用时,而不是作为 slot 使用时。

yangminglong 2014年9月4日 - 16:15

博主文章写得清晰明了易懂,感谢

回复
Leon 2014年11月25日 - 08:58

大赞博主!最近一直在看您的文章,收益颇多,谢谢!

回复
Joshua 2015年3月3日 - 21:40

豆子老师,你这个fileSave函数到最后没有把textEdit中的内容写到所打开的文件中啊,只是把它给了out这个变量。是不是呢?

回复
豆子 2015年3月9日 - 14:19

out是一个QTextStream类型的对象,<< 做了输出重定向,实际上是将文本内容输出到QTextStream,由QTextStream写入

回复
Joshua 2015年3月4日 - 09:57

豆子老师,为什么我按照上面的程序写法写出来进行保存操作后,再打开保存的文件,发现里面的内容并不是textedit里面的内容呢?

回复
别时容易00 2015年8月5日 - 19:26

豆子老师您好!非常感谢您的教程!

想请教一个问题,您说在这个演示中没有检查这个文件的实际类型是不是一个文本文件。想请教您能否简单讲解一下要怎样做这个检查?

回复
豆子 2015年8月16日 - 13:12

这个没有标准的办法检查,一般是尝试看是不是这种类型的文件,例如使用 MINE 这样的媒体类型库。

回复
豆子的小豆子 2015年9月5日 - 19:32

豆子我要给你生猴子,另外问一下函数声明写在private和private slots有什么区别吗

回复
豆子 2015年9月5日 - 21:47

private 是 C++ 关键字,表示私有函数;slots 是 Qt 的关键字,表示一个槽函数;private slots 就是一个私有的槽函数。

回复
豆子的小豆子 2015年9月5日 - 21:54

把那个open和save写在private里面好像也可以当槽函数使用。

回复
风出闹闹 2016年1月28日 - 13:50

为什么用QT creator是这样的
Starting C:\Users\Administrator\Desktop\workspace\filedialog-qt5\build-QtStudyRoad-Desktop_Qt_5_5_1_MSVC2013_32bit-Debug\debug\QtStudyRoad.exe...
程序异常结束。
C:\Users\Administrator\Desktop\workspace\filedialog-qt5\build-QtStudyRoad-Desktop_Qt_5_5_1_MSVC2013_32bit-Debug\debug\QtStudyRoad.exe crashed
而用VS2013是无法启动该程序,因为计算机丢失icuin51.dll。尝试重新安装该程序以解决问题

回复
豆子 2016年1月29日 - 15:00

我一直使用 Qt Creator,没有任何问题;感觉好像是路径不对,icuin51.dll 原本应该是在 bin 目录下的,使用 Qt Creator 应该是没有问题的

回复
风出闹闹 2016年1月29日 - 17:47

重启电脑后用VS2013居然好了,Qt creator变成了没有加调试器,加了debugging tools也好了,重启果然是修电脑的大神器。。。。

回复
nightwind 2016年1月29日 - 23:24

豆子老师你好,照着你的代码自己敲进去,发现ICON的图片显示不出来,但是路径正确,资源也是有。
然后下载了你的源码导入发现可以显示,于是我对比了一下每个文件,也确定没有错误,不知道什么原因图片还是显示不出来。

回复
橙子 2016年3月6日 - 20:21

是路径问题,加“:/”。我的是这样解决的。

回复
布鲁斯 2016年3月18日 - 22:07

加在哪?怎么加?貌似本来路径就有那个了

回复
青山 2016年7月21日 - 17:23

https://www.devbean.net/2012/08/qt-study-road-2-resource-files/
参考豆子之前的文章.
豆子的代码里qrc文件里指定了别名.

回复
青山 2016年7月21日 - 17:21

https://www.devbean.net/2012/08/qt-study-road-2-resource-files/
参考这里, 豆子的代码里qrc文件里指定了别名,而你手敲的代码这里没有指定别名.
要么指定别名, 要么路径填写完整

回复
Rechal 2016年3月14日 - 17:21

选择了文件打开后程序就会异常结束是因为什么呢?save操作也有这样的问题
Starting C:\lxj\Qt\build-mainwindow-Desktop_Qt_5_5_1_MSVC2010_32bit-Debug\debug\mainwindow.exe...
程序异常结束。
C:\lxj\Qt\build-mainwindow-Desktop_Qt_5_5_1_MSVC2010_32bit-Debug\debug\mainwindow.exe crashed

回复
豆子 2016年3月14日 - 22:04

程序异常结束一般是因为内存的问题,可能是前面会有哪里有错误,这个需要仔细查看的

回复
布鲁斯 2016年3月18日 - 21:59

为什么我的打开和保存图标没有显示出来?检查了代码和资源链接都没问题啊

回复
Rachel le 2016年3月20日 - 15:47

图片资源是png格式的吗?

回复
布鲁斯 2016年3月24日 - 10:39

找到原因了,我忘了在.pro文件添加 “RESOURCES = **.qrc” 这句代码了。

回复
豆子 2016年3月20日 - 16:23

重新运行一下 qmake,或者重新构建一下试试

回复
吴柄谊 2016年4月14日 - 17:12

豆老师您好,这个打开txt 文件没问题,但若是打开mda 或 dat 等二进制文件则显示乱码??若想将二进制文件打开并用字符串显示在textEdit中的话程序该怎么改动??(Qt刚学两天。。)

回复
豆子 2016年4月22日 - 16:34

二进制文件不能直接显示,如果你想以 0、1 显示二进制文件,需要自己一个位一个位的读取(或者读取四个位,按照十六进制显示),然后将其显示出来。

回复
shx 2016年4月16日 - 21:38

豆子大哥
请问怎么可以将文件保存到指定目录下呢
就是不需要对话框的这种
我在编码时指定目录
查了好久也没找到该怎么去弄
请指教

回复
豆子 2016年4月22日 - 16:41

不要用户选择的话,你只需要直接设置 QFile 的路径就可以了。

回复
张一凡 2016年5月16日 - 00:58

豆子老师你好,我想问一下如何在头文件中声明textEdit,就是格式是什么样子。谢谢。

回复
豆子 2016年5月20日 - 15:06

在 class 声明中添加QTextEdit *textEdit;就可以了

回复
张二嘎 2016年12月6日 - 09:58

不好意思提一个比较弱鸡的问题,为什么这里的connect函数不需要域QObject::connect?

回复
豆子 2016年12月6日 - 21:12

确切的说,这并不是“域”(C++ 里面好像并没有这个名词),QObject::connect 是调用了 QObject 类的 static 函数。因为这里的类都是 QObject 的子类,继承了这些 static 函数,所以就不需要 QObject 前缀了

回复
浮游 2016年12月17日 - 13:55

豆老师,为什么用QPushputton 和 QAction 的时候可以在class中直接声明,使用QTextEditde时候直接声明会报错,加上类的前置声明才可以用

回复
豆子 2016年12月18日 - 10:04

这可能是因为在其它头文件中,比如 QFileDialog 中已经有过 QPushButton 的声明,所以不需要额外再次声明

回复
铁人28号 2017年8月1日 - 09:56

豆老师,请教一下菜单栏的问题。我在design里面加上菜单栏以后,auto file = &(UI->menubarfile),file->addaction(actionname).然后就开始报错,说ui里面没有这些object,连之后的textedit也识别不了了。请问这是什么问题?如果我直接写,不在designer里面画就完全没问题。

回复
铁人28号 2017年8月1日 - 09:58

而且我这个项目里面就算没有引用ui->menubar,在designer里面画了,在mainwindow也不显示。

回复
豆子 2017年8月1日 - 21:36

有没有调用 setupUi() 函数?或者应该在这个函数之后再使用组件?

回复
John Wong 2018年7月2日 - 15:55

豆子老师真是育人不倦啊!致敬!

回复
bozhou 2018年8月31日 - 00:22

老师您好:mainwindow.cpp里面有一句:“textEdit = new QTextEdit(this);”
如果在textEdit前面加上一个:Qtext Edit *
就会在我选择了要打开的文件之后直接显示程序异常结束呢?

回复
豆子 2018年9月2日 - 15:15

textEdit = new QTextEdit(this); 是初始化了作为成员变量的 textEdit,以便在后面打开文件时使用这个变量。如果你改为 QTextEdit *textEdit = new QTextEdit(this);,则是在构造函数里面创建了一个新的变量 textEdit,虽然名字一样,但这个变量的作用域是构造函数,在构造函数以外,是无法使用 textEdit 这个名字的。因此,当你选择要打开的文件的时候,代码还是使用的成员变量 textEdit,但此时,这个成员变量并没有初始化,也就是说,成员变量 textEdit 是一个野指针,所以程序会异常结束

回复
Huang Zhen 2019年11月11日 - 10:33

getOpenFileName和getSaveFileName看起来是一样的,为何要做成两个函数呢?原来getOpenFileName只能选择已经存在的文件,而getSaveFileName可以自己输入一个文件名用来保存。我觉得可以加上这部分内容,以免读者看的时候疑惑。

回复
Lau 2019年11月15日 - 20:44

刚开始学习Qt,为啥下载不了源代码?/:笑哭

回复
豆子 2019年11月21日 - 22:05

我这里测试是可以下载的

回复
lei ming 2020年2月28日 - 18:14

初学Qt,希望答主能写一章关于ui_mainwindow的介绍,现在创建文件好像自带这个。

回复
豆子 2020年4月21日 - 13:24

ui_mainwindow 是 Qt Desinger 生成的文件,用于记录界面设计的,只要在 Qt Creator 中拖放就可以了。这个文件是自动生成的,以 XML 格式描述界面用的

回复
阳光 2020年11月19日 - 09:52

请教个问题,用 file_name = QFileDialog::getOpenFileName(this,
tr("选择烧录文件"),
QCoreApplication::applicationDirPath(),
tr("Bin File (*.bin)"));
第一次打开的时候特别慢(后面再去打开的话速度就是正常的),button按下去后差不多要5秒才跳出来选择文件的对话框,请帮忙看看是否有需要特别设置的地方。
QT版本5.14.1, 编译器是mingw32.

回复
豆子 2020年11月21日 - 16:11

这个应该没有特殊设置,不知道是什么原因。会不会因为文件夹内文件过多?

回复
成年雄性大熊猫 2021年3月20日 - 18:15

豆子老师,为什么用openfile打开的文件不仅内容没显示出来,而且文件内容也没了
不管是先用saveopen保存的还是提前写在txt里面的内容都是的

回复
h x 2022年6月7日 - 14:22

下面的源代码。下载不了了。 豆子 hxd更新一下呀

回复
豆子 2022年6月8日 - 23:29

我这里是可以下载的

回复

回复 豆子 取消回复

关于我

devbean

devbean

豆子,生于山东,定居南京。毕业于山东大学软件工程专业。软件工程师,主要关注于 Qt、Angular 等界面技术。

主题 Salodad 由 PenciDesign 提供 | 静态文件存储由又拍云存储提供 | 苏ICP备13027999号-2