跳转到内容
新建笔记

Qt 未使用参数:Q_UNUSED、maybe_unused 与绘制事件

参数保留在接口中,但当前实现不用它

跳转到“参数保留在接口中,但当前实现不用它”

重写 paintEvent(QPaintEvent *event) 时,如果每次都绘制整幅背景而不检查事件区域,参数仍由 Qt 的接口规定。Q_UNUSED(event); 表达“这里有意不用这个参数”,可消除相应的未使用参数警告。它不改变函数签名,也不表示程序从此不能访问这个变量。Qt 宏说明

先区分三种处理方式:

写法适用情况
在函数体写 Q_UNUSED(event);保留有意义的参数名,继续使用 Qt 风格
在参数声明写 [[maybe_unused]]使用 C++17 标准属性,允许该参数在部分配置中不被使用
定义时省略参数名,如 void f(int)实现确定不需要该值;声明处仍可保留参数名

编译器是否报告警告取决于警告选项。这些写法不会修复忘记处理参数导致的业务错误;如果绘制策略本应依赖事件区域,就应该实际使用它。

Qt 的实现通过丢弃表达式的值来处理未使用警告。不要自行重新定义 Q_UNUSED,也不要把它当作不会求值的语法:传入 counter++ 会修改计数器,传入函数调用也可能执行函数。通常只传变量名。

模板类型参数 T 不是变量,不能写 Q_UNUSED(T)。模板函数中的值参数可以照常处理;不需要的类型参数通常保留在模板声明中,或省略其名字。这与运行时表达式不同。

保留背景绘制场景的完整例子

跳转到“保留背景绘制场景的完整例子”

下面程序使用 Qt 6 Widgets 和 C++17。默认背景在内存中创建,避免把不存在的资源路径当成可运行前提;传入图片文件或 :/... 资源路径时会检查加载结果。paintEvent 把背景缩放到窗口矩形,QPainter 只在绘制期间使用。

main.cpp:

#include <QApplication>
#include <QImage>
#include <QPainter>
#include <QPaintEvent>
#include <QPixmap>
#include <QWidget>
#include <QtGlobal>
#include <cassert>
#include <iostream>
#include <utility>
class BackgroundWidget final : public QWidget {
public:
explicit BackgroundWidget(QPixmap background)
: background_(std::move(background)) {}
protected:
void paintEvent(QPaintEvent *event) override {
Q_UNUSED(event);
QPainter painter(this);
painter.drawPixmap(rect(), background_);
}
private:
QPixmap background_;
};
void namedParameter(int value) { Q_UNUSED(value); }
void attributedParameter([[maybe_unused]] int value) {}
void unnamedParameter(int) {}
int main(int argc, char **argv) {
QApplication app(argc, argv);
int counter = 0;
Q_UNUSED(counter++); // Demonstrates evaluation; use a plain name normally.
assert(counter == 1);
namedParameter(1);
attributedParameter(2);
unnamedParameter(3);
QPixmap background(4, 4);
background.fill(Qt::darkCyan);
if (argc == 2 && !background.load(QString::fromLocal8Bit(argv[1]))) {
std::cerr << "Cannot load background\n";
return 1;
}
BackgroundWidget widget(background);
widget.resize(80, 60);
QImage frame(widget.size(), QImage::Format_ARGB32);
frame.fill(Qt::transparent);
widget.render(&frame); // Exercises paintEvent without an interactive loop.
assert(!frame.isNull());
if (argc == 1) assert(frame.pixelColor(40, 30) == QColor(Qt::darkCyan));
std::cout << "unused parameters and background paint passed\n";
}

CMakeLists.txt:

cmake_minimum_required(VERSION 3.20)
project(UnusedParameters LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt6 REQUIRED COMPONENTS Widgets)
add_executable(unused_parameters main.cpp)
target_link_libraries(unused_parameters PRIVATE Qt6::Widgets)

这是自动结束的绘制检查。交互程序需要显示窗口并进入事件循环;按自己的界面需求决定保留纵横比、裁剪或拉伸。若沿用原来的 :/pics/images/background.jpg,还须把实际图片编译进资源并核对 prefix/alias,见资源和素材。

原记录讨论的是 Q_UNUSED 这一种宏,不能据此推导所有 Qt 宏都无运行开销或都会丢弃参数求值。来源:原始记录、Qt 预处理支持。