Files
张宗平 13b3ebbe14 课程代码仓库初始化:Part1 (144) + Part3 (29) 全量生成与验证
把川大 wiki「02.Qt方向」课程代码整理为 CMake 管理的可编译运行项目。

Part1 C/C++ 强化 (p01/, 144 目标, host gcc/g++ 构建, 全绿):
- 修复全部编译失败:补 <cstring>/<fstream>/<iomanip>/<vector> 等缺失头
  (common_fix + infer_stl_includes 自动检测注入)、修正 pause() 壳注入
  (改检测已转换后的 pause 调用)、namespace 提升出函数体、const 成员函数
  正确性、dedupe 不再破坏函数重载集、K&R 隐式 int / 动态异常规范等
  C++17 移除特性的可编译等价改写。
- 目录采用深缩写 p01/ch04/s03/ (原 part1_cpp/ch04_class_object/03_ctor_dtor)。

Part3 Qt 桌面 (p03/, 29 目标, 隔离 Qt 5.14.2 构建, 全绿):
- gen_part3.py: Qt 外壳模板 (main+QApplication+show, QTimer 自动退出便于
  offscreen 验证)、AUTOMOC + .moc include、rewrite_* 处理散文混入/重载/
  资源依赖、生成占位 png/gif + .qrc + rundata 样例数据。
- 修正 QLable 笔误、全角分号、.→->、Windows 路径、QApplication 阻塞事件
  循环改为 QCoreApplication 等。

任务1 概念/版本验证:
- tools/std_probe.py: 跨 -std= 编译探针 (--pedantic-errors 让已废除特性硬失败)。
- tools/demo_versions/: K&R 隐式 int、三目左值、void* 转换、enum 赋整、
  const 经指针、动态异常规范 共 6 个跨版本演示。
- docs/VERSION_NOTES.md: 每条「原文说法→C17/C++17 是否成立→何版本成立→已验证」。

文档: 顶层 README、docs/SOURCE_PAGES.md (页面→目录映射)、
docs/ERRATA.md (Part1 修正)、docs/ERRATA_part3.md (Part3 修正)。
另修复 tools/run.sh / run_qt.sh 的 ${1:?...} 引号语法 bug。

隔离 Qt 验证: ldd 0 系统 Qt 引用; 173/173 目标全绿; p03 offscreen 运行通过。
2026-06-30 14:16:55 +08:00

1 line
13 KiB
JSON
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"id":"58954540","type":"page","status":"current","title":"8 常用控件","version":{"by":{"type":"known","username":"ethanliu","userKey":"2c90931b6cfb654f016d5c69becc0001","profilePicture":{"path":"/images/icons/profilepics/default.svg","width":48,"height":48,"isDefault":true},"displayName":"刘浩","_links":{"self":"https://wiki.suncaper.net/rest/api/user?key=2c90931b6cfb654f016d5c69becc0001"},"_expandable":{"status":""}},"when":"2022-07-09T01:51:25.000Z","message":"","number":1,"minorEdit":false,"hidden":false,"_links":{"self":"https://wiki.suncaper.net/rest/experimental/content/58954540/version/1"},"_expandable":{"content":"/rest/api/content/58954540"}},"body":{"storage":{"value":"<p>Qt为我们应用程序界面开发提供的一系列的控件,下面我们介绍两种最常用一些控件,所有控件的使用方法我们都可以通过帮助文档获取。</p><h1><ac:structured-macro ac:name=\"anchor\" ac:schema-version=\"1\" ac:macro-id=\"e6318e8c-d194-4b4d-8b73-f48ec30c4a4f\"><ac:parameter ac:name=\"\">_Toc466556789</ac:parameter></ac:structured-macro><ac:structured-macro ac:name=\"anchor\" ac:schema-version=\"1\" ac:macro-id=\"1e8fbaa5-4834-47b0-a79a-6dd3f1fa2e49\"><ac:parameter ac:name=\"\">_Toc471842021</ac:parameter></ac:structured-macro>8.1 QLabel控件使用</h1><p>QLabel是我们最常用的控件之一,其功能很强大,我们可以用来显示文本,图片和动画等。</p><h2><ac:structured-macro ac:name=\"anchor\" ac:schema-version=\"1\" ac:macro-id=\"c2a4d421-90b2-426a-a450-b0a7e0fd0fe2\"><ac:parameter ac:name=\"\">_Toc471842022</ac:parameter></ac:structured-macro>显示文字 (普通文本、html</h2><p>通过QLabel类的setText函数设置显示的内容:</p><ac:structured-macro ac:name=\"code\" ac:schema-version=\"1\" ac:macro-id=\"0bb1710e-fe99-4aa5-8ae9-f988e34ace30\"><ac:parameter ac:name=\"language\">cpp</ac:parameter><ac:plain-text-body><![CDATA[voidsetText(const QString &)]]></ac:plain-text-body></ac:structured-macro><p><br /></p><ul><li>可以显示普通文本字符串</li></ul><ac:structured-macro ac:name=\"code\" ac:schema-version=\"1\" ac:macro-id=\"b81bc299-540b-4f63-bdfb-b11a65799042\"><ac:parameter ac:name=\"language\">cpp</ac:parameter><ac:plain-text-body><![CDATA[QLable *label = new QLable;\nlabel->setText(\"Hello, World!\");]]></ac:plain-text-body></ac:structured-macro><p><br /></p><ul><li>可以显示HTML格式的字符串</li></ul><p>比如显示一个链接:</p><ac:structured-macro ac:name=\"code\" ac:schema-version=\"1\" ac:macro-id=\"081fd765-ed28-4170-ab59-cb74bc1e0dd3\"><ac:parameter ac:name=\"language\">cpp</ac:parameter><ac:plain-text-body><![CDATA[QLabel * label = new QLabel(this);\nlabel ->setText(\"Hello, World\");\nlabel ->setText(\"<h1><a href=\\\"https://www.baidu.com\\\">百度一下</a></h1>\");\nlabel ->setOpenExternalLinks(true);]]></ac:plain-text-body></ac:structured-macro><p><br />其中setOpenExternalLinks()函数是用来设置用户点击链接之后是否自动打开链接,如果参数指定为true则会自动打开。</p><h2><ac:structured-macro ac:name=\"anchor\" ac:schema-version=\"1\" ac:macro-id=\"8b57c249-23a9-4943-81a0-d5a191f61bd7\"><ac:parameter ac:name=\"\">_Toc471842023</ac:parameter></ac:structured-macro>显示图片</h2><p>可以使用QLabel的成员函数setPixmap设置图片</p><ac:structured-macro ac:name=\"code\" ac:schema-version=\"1\" ac:macro-id=\"80148b7a-5d94-419e-b872-400d37609cbb\"><ac:parameter ac:name=\"language\">cpp</ac:parameter><ac:plain-text-body><![CDATA[voidsetPixmap(const QPixmap &)]]></ac:plain-text-body></ac:structured-macro><p><br />首先定义QPixmap对象</p><ac:structured-macro ac:name=\"code\" ac:schema-version=\"1\" ac:macro-id=\"64d8fa15-16f6-427f-b998-8184a97066db\"><ac:parameter ac:name=\"language\">cpp</ac:parameter><ac:plain-text-body><![CDATA[QPixmap pixmap;]]></ac:plain-text-body></ac:structured-macro><p><br />然后加载图片</p><ac:structured-macro ac:name=\"code\" ac:schema-version=\"1\" ac:macro-id=\"1c8a0f17-463e-478b-95d6-3a2cf5dc798c\"><ac:parameter ac:name=\"language\">cpp</ac:parameter><ac:plain-text-body><![CDATA[pixmap.load(\":/Image/boat.jpg\");]]></ac:plain-text-body></ac:structured-macro><p><br />最后将图片设置到QLabel中</p><ac:structured-macro ac:name=\"code\" ac:schema-version=\"1\" ac:macro-id=\"b8cb4e0a-6e57-4ef5-afdd-da7f7d60dc29\"><ac:parameter ac:name=\"language\">cpp</ac:parameter><ac:plain-text-body><![CDATA[QLabel *label = new QLabel;\nlabel.setPixmap(pixmap);]]></ac:plain-text-body></ac:structured-macro><p><br /></p><h2><ac:structured-macro ac:name=\"anchor\" ac:schema-version=\"1\" ac:macro-id=\"513f2ac1-69bf-4210-a347-78b11420c9fc\"><ac:parameter ac:name=\"\">_Toc471842024</ac:parameter></ac:structured-macro>显示动画</h2><p>可以使用QLabel 的成员函数setMovie加载动画,可以播放gif格式的文件</p><ac:structured-macro ac:name=\"code\" ac:schema-version=\"1\" ac:macro-id=\"6b35d17a-0340-4365-8e02-f2c497cd4a7f\"><ac:parameter ac:name=\"language\">cpp</ac:parameter><ac:plain-text-body><![CDATA[voidsetMovie(QMovie * movie)]]></ac:plain-text-body></ac:structured-macro><p><br />首先定义QMovied对象,并初始化:</p><ac:structured-macro ac:name=\"code\" ac:schema-version=\"1\" ac:macro-id=\"bc921244-724d-4097-ac3d-24e38c077f79\"><ac:parameter ac:name=\"language\">cpp</ac:parameter><ac:plain-text-body><![CDATA[QMovie *movie = new QMovie(\":/Mario.gif\");]]></ac:plain-text-body></ac:structured-macro><p><br />播放加载的动画:</p><ac:structured-macro ac:name=\"code\" ac:schema-version=\"1\" ac:macro-id=\"b091f0f0-d2fb-4d8f-9690-8eaf7106c1c2\"><ac:parameter ac:name=\"language\">cpp</ac:parameter><ac:plain-text-body><![CDATA[movie->start();]]></ac:plain-text-body></ac:structured-macro><p><br />将动画设置到QLabel中:</p><ac:structured-macro ac:name=\"code\" ac:schema-version=\"1\" ac:macro-id=\"d259b680-7f5c-4f3e-b6d3-af11e307f734\"><ac:parameter ac:name=\"language\">cpp</ac:parameter><ac:plain-text-body><![CDATA[QLabel *label = new QLabel\nlabel->setMovie(movie);]]></ac:plain-text-body></ac:structured-macro><p><br /></p><h1><ac:structured-macro ac:name=\"anchor\" ac:schema-version=\"1\" ac:macro-id=\"9f6252c0-3cae-4d6f-90d3-3ba2bfee66f1\"><ac:parameter ac:name=\"\">_Toc466556790</ac:parameter></ac:structured-macro><ac:structured-macro ac:name=\"anchor\" ac:schema-version=\"1\" ac:macro-id=\"5c8adc7e-c542-4e27-8de1-9c21d6c099f0\"><ac:parameter ac:name=\"\">_Toc471842025</ac:parameter></ac:structured-macro>8.2 QLineEdit</h1><p>Qt提供的单行文本编辑框。</p><h2>设置/获取内容</h2><ul><li>获取编辑框内容使用text(),函数声明如下:</li></ul><ac:structured-macro ac:name=\"code\" ac:schema-version=\"1\" ac:macro-id=\"40ce48a3-3843-46ce-a4c7-b6d9d7f436cf\"><ac:parameter ac:name=\"language\">cpp</ac:parameter><ac:plain-text-body><![CDATA[QStringtext() const]]></ac:plain-text-body></ac:structured-macro><p><br /></p><ul><li>设置编辑框内容</li></ul><ac:structured-macro ac:name=\"code\" ac:schema-version=\"1\" ac:macro-id=\"b5f4a7d0-0d26-4a63-af4c-74d8d646f20b\"><ac:parameter ac:name=\"language\">cpp</ac:parameter><ac:plain-text-body><![CDATA[voidsetText(const QString &)]]></ac:plain-text-body></ac:structured-macro><p><br /></p><h2>设置显示模式</h2><p>使用QLineEdit类的setEchoMode () 函数设置文本的显示模式,函数声明:</p><ac:structured-macro ac:name=\"code\" ac:schema-version=\"1\" ac:macro-id=\"05477df0-eb82-49cb-a071-ade37c3950cc\"><ac:parameter ac:name=\"language\">cpp</ac:parameter><ac:plain-text-body><![CDATA[voidsetEchoMode(EchoMode mode)]]></ac:plain-text-body></ac:structured-macro><p><br />EchoMode是一个枚举类型,一共定义了四种显示模式:</p><ul><li>QLineEdit::Normal 模式显示方式,按照输入的内容显示。</li><li>QLineEdit::NoEcho 不显示任何内容,此模式下无法看到用户的输入。</li><li>QLineEdit::Password 密码模式,输入的字符会根据平台转换为特殊字符。</li><li>QLineEdit::PasswordEchoOnEdit 编辑时显示字符否则显示字符作为密码。</li></ul><p>另外,我们再使用QLineEdit显示文本的时候,希望在左侧留出一段空白的区域,那么,就可以使用QLineEdit给我们提供的setTextMargins函数:</p><ac:structured-macro ac:name=\"code\" ac:schema-version=\"1\" ac:macro-id=\"fb4d8a50-616f-4c02-b8c6-4ea97455aa47\"><ac:parameter ac:name=\"language\">cpp</ac:parameter><ac:plain-text-body><![CDATA[void setTextMargins(int left, int top, int right, int bottom)]]></ac:plain-text-body></ac:structured-macro><p><br />用此函数可以指定显示的文本与输入框上下左右边界的间隔的像素数。</p><h1><ac:structured-macro ac:name=\"anchor\" ac:schema-version=\"1\" ac:macro-id=\"0f8baf67-cbfe-407f-b0f5-bd84f4f8779e\"><ac:parameter ac:name=\"\">_Toc466556791</ac:parameter></ac:structured-macro><ac:structured-macro ac:name=\"anchor\" ac:schema-version=\"1\" ac:macro-id=\"562f9533-d43f-45f9-903c-771b228f822b\"><ac:parameter ac:name=\"\">_Toc471842026</ac:parameter></ac:structured-macro>8.3 其他控件</h1><p>Qt中控件的使用方法可参考Qt提供的帮助文档。</p><h1><ac:structured-macro ac:name=\"anchor\" ac:schema-version=\"1\" ac:macro-id=\"cfbcfae2-08e3-4d30-b93a-0adcb91161ba\"><ac:parameter ac:name=\"\">_Toc466556794</ac:parameter></ac:structured-macro><ac:structured-macro ac:name=\"anchor\" ac:schema-version=\"1\" ac:macro-id=\"fa949a23-9dab-4306-87d5-e8d89cc3e24f\"><ac:parameter ac:name=\"\">_Toc471842027</ac:parameter></ac:structured-macro>8.4 自定义控件</h1><p>在搭建Qt窗口界面的时候,在一个项目中很多窗口,或者是窗口中的某个模块会被经常性的重复使用。一般遇到这种情况我们都会将这个窗口或者模块拿出来做成一个独立的窗口类,以备以后重复使用。<br />在使用Qt的ui文件搭建界面的时候,工具栏栏中只为我们提供了标准的窗口控件,如果我们想使用自定义控件怎么办?<br />例如:我们从QWidget派生出一个类SmallWidget,实现了一个自定窗口,</p><ac:structured-macro ac:name=\"code\" ac:schema-version=\"1\" ac:macro-id=\"086a9af9-185c-4120-82a0-e5dc464bd987\"><ac:parameter ac:name=\"language\">cpp</ac:parameter><ac:plain-text-body><![CDATA[// smallwidget.h\nclass SmallWidget : public QWidget\n{\nQ_OBJECT\npublic:\nexplicit SmallWidget(QWidget *parent = 0);\nsignals:\npublic slots:\nprivate:\nQSpinBox* spin;\nQSlider* slider;\n};\n// smallwidget.cpp\nSmallWidget::SmallWidget(QWidget *parent) : QWidget(parent)\n{\nspin = new QSpinBox(this);\nslider = new QSlider(Qt::Horizontal, this);\n// 创建布局对象\nQHBoxLayout* layout = new QHBoxLayout;\n// 将控件添加到布局中\nlayout->addWidget(spin);\nlayout->addWidget(slider);\n// 将布局设置到窗口中\nsetLayout(layout);\n// 添加消息响应\nconnect(spin,\nstatic_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),\nslider, &QSlider::setValue);\nconnect(slider, &QSlider::valueChanged,\nspin, &QSpinBox::setValue);\n}]]></ac:plain-text-body></ac:structured-macro><p><br /><ac:image ac:height=\"111\" ac:width=\"323\"><ri:attachment ri:filename=\"worddav9b7147e099a681a2621521b2bffff005.png\" /></ac:image><br />那么这个SmallWidget可以作为独立的窗口显示,也可以作为一个控件来使用:<br />打开Qt的.ui文件,因为SmallWidget是派生自Qwidget类,所以需要在ui文件中先放入一个QWidget控件, 然后再上边鼠标右键<br /><ac:image ac:height=\"252\" ac:width=\"330\"><ri:attachment ri:filename=\"worddav1eedd84a62cf68909d2177c3c8b88052.png\" /></ac:image><br />弹出提升窗口部件对话框<br /><ac:image ac:height=\"472\" ac:width=\"508\"><ri:attachment ri:filename=\"worddava76cd1a701b7864f4326a1d50869d8ab.png\" /></ac:image><br />添加要提升的类的名字,然后选择 添加 <br /><ac:image ac:height=\"472\" ac:width=\"508\"><ri:attachment ri:filename=\"worddav9bde7419e59d87778afa6cc46cb539a8.png\" /></ac:image><br />添加之后,类名会显示到上边的列表框中,然后单击提升按钮,完成操作.<br />我们可以看到, 这个窗口对应的类从原来的QWidget变成了SmallWidget<br /><ac:image ac:height=\"22\" ac:width=\"268\"><ri:attachment ri:filename=\"worddav076076b5bde22162b5f1bfda6d161079.png\" /></ac:image><br />再次运行程序,这个widget_3中就能显示出我们自定义的窗口了.</p>","representation":"storage","_expandable":{"content":"/rest/api/content/58954540"}},"_expandable":{"editor":"","view":"","export_view":"","styled_view":"","anonymous_export_view":""}},"extensions":{"position":47},"_links":{"webui":"/pages/viewpage.action?pageId=58954540","edit":"/pages/resumedraft.action?draftId=58954540","tinyui":"/x/LJODAw","collection":"/rest/api/content","base":"https://wiki.suncaper.net","context":"","self":"https://wiki.suncaper.net/rest/api/content/58954540"},"_expandable":{"container":"/rest/api/space/2CT","metadata":"","operations":"","children":"/rest/api/content/58954540/child","restrictions":"/rest/api/content/58954540/restriction/byOperation","history":"/rest/api/content/58954540/history","ancestors":"","descendants":"/rest/api/content/58954540/descendant","space":"/rest/api/space/2CT"}}