如何在不使用 QMainWindow 的情况下向 QWidget 添加背景图像?
How to add a background image to a QWidget without using QMainWindow?
编辑: 问题还没有解决,我暂时使用了@Scheff
的答案作为解决方法。
是否可以将图像作为背景添加到以 QWidget 作为基础创建的 Qt 小部件应用程序中 class?我在这里根本没有使用 QMainWindow。
在Qt Creator中,您可以在创建新项目的同时生成框架源代码文件。如果您选择 QWidget 作为基础 class,并尝试通过更改小部件样式 sheet 添加图像作为背景(手动或从 IDE 的设计部分),构建项目时图像不会显示。如果可能,我该如何解决?
我创建一个Qt资源文件,添加一个图片(在源代码目录下),并设置样式sheet,就这样。但是如果我用
添加背景颜色
Widget->setStyleSheet(QString::fromUtf8("#Widget {background-color: rgb(55,55,55)};"));
在 ui_widget.h 中,它工作正常并在构建后显示。
如果我从 Qt Creator 中预览小部件,图像会出现,但在构建和 运行 之后不会出现。
这里在Qt Creator中选择QWidget作为基础class:
这是main.cpp:
#include "widget.h"
#include <QtCore/qglobal.h>
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
这是ui_widget.h:
#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_Widget
{
public:
void setupUi(QWidget *Widget)
{
if (Widget->objectName().isEmpty())
Widget->setObjectName(QString::fromUtf8("Widget"));
Widget->resize(600, 150);
// I add this line, if I changed the style sheet to a simple background color it shows up with no problem {background-color: rgb(1,1,200)}
Widget->setStyleSheet(QString::fromUtf8("#Widget {background-image: url(:/pic.jpg);}"));
retranslateUi(Widget);
QMetaObject::connectSlotsByName(Widget);
} // setupUi
void retranslateUi(QWidget *Widget)
{
Widget->setWindowTitle(QApplication::translate("Widget", "Widget", nullptr));
} // retranslateUi
};
namespace Ui {
class Widget: public Ui_Widget {};
} // namespace Ui
QT_END_NAMESPACE
这是widget.h:
#include <QtCore/qglobal.h>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
};
这是widget.cpp:
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); }
Widget::~Widget() { delete ui; }
很抱歉添加了整个生成的代码,但它可能会有所帮助,谢谢。
出于好奇,我尝试了自己的 MCVE。
C++ 源码testQWidgetBackgroundImage.cc
:
// Qt header:
#include <QtWidgets>
// main application
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// setup GUI
QWidget qWinMain;
qWinMain.setWindowTitle("Test Background Image");
qWinMain.resize(640, 480);
qWinMain.setObjectName("Widget");
qWinMain.setStyleSheet("#Widget { background-image: url(cat.jpg); }");
qWinMain.show();
// runtime loop
return app.exec();
}
构建脚本CMakeLists.txt
:
project(QWidgetBackgroundImage)
cmake_minimum_required(VERSION 3.10.0)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
find_package(Qt5Widgets CONFIG REQUIRED)
include_directories("${CMAKE_SOURCE_DIR}")
add_executable(testQWidgetBackgroundImage testQWidgetBackgroundImage.cc)
target_link_libraries(testQWidgetBackgroundImage Qt5::Widgets)
输出:
因此,至少在使用 VS 2017 和 Qt 5.13 的 Windows 10 中,我能够显示带有样式 sheet 背景图像的普通 QWidget
。
这与 Qt Style Sheets Reference – background 中记录的内容一致:
Shorthand notation for setting the background. Equivalent to specifying background-color, background-image, background-repeat, and/or background-position.
This property is supported by QAbstractItemView subclasses, QAbstractSpinBox subclasses, QCheckBox, QComboBox, QDialog, QFrame, QGroupBox, QLabel, QLineEdit, QMenu, QMenuBar, QPushButton, QRadioButton, QSplitter, QTextEdit, QToolTip, and plain QWidgets.
注:
我必须承认我对Qt资源的使用没有任何经验。因此,我提供了 URL 和 url(cat.jpg)
一样,这导致尝试从本地当前工作目录中的文件加载(成功如上面的快照所示)。带有 :
的前缀(例如 url(:/cat.jpg)
)将改为寻址 Qt 资源中的条目。
进一步阅读:The Qt Resource System
阅读文档后。在上面的 link 中,我注意到使用起来并没有那么复杂,并对上面的 MCVE 进行了一些修改:
C++ 源文件 testQWidgetBackgroundImage.cc
// Qt header:
#include <QtWidgets>
// main application
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// setup GUI
QWidget qWinMain;
qWinMain.setWindowTitle("Test Background Image");
qWinMain.resize(640, 480);
qWinMain.setObjectName("Widget");
qWinMain.setStyleSheet("#Widget { background-image: url(:/cat.jpg); }");
qWinMain.show();
// runtime loop
return app.exec();
}
实际上,唯一的变化是 url(cat.jpg)
→ url(:/cat.jpg)
。
Qt 资源文件testQWidgetBackgroundImage.qrc
:
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource>
<file>cat.jpg</file>
</qresource>
</RCC>
Qt 工程文件testQWidgetBackgroundImage.pro
:
SOURCES = testQWidgetBackgroundImage.cc
RESOURCES = testQWidgetBackgroundImage.qrc
QT += widgets
在 cygwin64 中构建并测试:
$ qmake-qt5 testQWidgetBackgroundImage.pro
$ make && ./testQWidgetBackgroundImage
g++ -c -fno-keep-inline-dllexport -D_GNU_SOURCE -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtWidgets -isystem /usr/include/qt5/QtGui -isystem /usr/include/qt5/QtCore -I. -I/usr/lib/qt5/mkspecs/cygwin-g++ -o testQWidgetBackgroundImage.o testQWidgetBackgroundImage.cc
/usr/lib/qt5/bin/rcc -name testQWidgetBackgroundImage testQWidgetBackgroundImage.qrc -o qrc_testQWidgetBackgroundImage.cpp
g++ -c -fno-keep-inline-dllexport -D_GNU_SOURCE -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtWidgets -isystem /usr/include/qt5/QtGui -isystem /usr/include/qt5/QtCore -I. -I/usr/lib/qt5/mkspecs/cygwin-g++ -o qrc_testQWidgetBackgroundImage.o qrc_testQWidgetBackgroundImage.cpp
g++ -o testQWidgetBackgroundImage.exe testQWidgetBackgroundImage.o qrc_testQWidgetBackgroundImage.o -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread
Qt Version: 5.9.4
输出:
编辑: 问题还没有解决,我暂时使用了@Scheff
的答案作为解决方法。
是否可以将图像作为背景添加到以 QWidget 作为基础创建的 Qt 小部件应用程序中 class?我在这里根本没有使用 QMainWindow。
在Qt Creator中,您可以在创建新项目的同时生成框架源代码文件。如果您选择 QWidget 作为基础 class,并尝试通过更改小部件样式 sheet 添加图像作为背景(手动或从 IDE 的设计部分),构建项目时图像不会显示。如果可能,我该如何解决?
我创建一个Qt资源文件,添加一个图片(在源代码目录下),并设置样式sheet,就这样。但是如果我用
添加背景颜色Widget->setStyleSheet(QString::fromUtf8("#Widget {background-color: rgb(55,55,55)};"));
在 ui_widget.h 中,它工作正常并在构建后显示。
如果我从 Qt Creator 中预览小部件,图像会出现,但在构建和 运行 之后不会出现。
这里在Qt Creator中选择QWidget作为基础class:
这是main.cpp:
#include "widget.h"
#include <QtCore/qglobal.h>
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
这是ui_widget.h:
#include <QtCore/QVariant>
#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_Widget
{
public:
void setupUi(QWidget *Widget)
{
if (Widget->objectName().isEmpty())
Widget->setObjectName(QString::fromUtf8("Widget"));
Widget->resize(600, 150);
// I add this line, if I changed the style sheet to a simple background color it shows up with no problem {background-color: rgb(1,1,200)}
Widget->setStyleSheet(QString::fromUtf8("#Widget {background-image: url(:/pic.jpg);}"));
retranslateUi(Widget);
QMetaObject::connectSlotsByName(Widget);
} // setupUi
void retranslateUi(QWidget *Widget)
{
Widget->setWindowTitle(QApplication::translate("Widget", "Widget", nullptr));
} // retranslateUi
};
namespace Ui {
class Widget: public Ui_Widget {};
} // namespace Ui
QT_END_NAMESPACE
这是widget.h:
#include <QtCore/qglobal.h>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
};
这是widget.cpp:
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); }
Widget::~Widget() { delete ui; }
很抱歉添加了整个生成的代码,但它可能会有所帮助,谢谢。
出于好奇,我尝试了自己的 MCVE。
C++ 源码testQWidgetBackgroundImage.cc
:
// Qt header:
#include <QtWidgets>
// main application
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// setup GUI
QWidget qWinMain;
qWinMain.setWindowTitle("Test Background Image");
qWinMain.resize(640, 480);
qWinMain.setObjectName("Widget");
qWinMain.setStyleSheet("#Widget { background-image: url(cat.jpg); }");
qWinMain.show();
// runtime loop
return app.exec();
}
构建脚本CMakeLists.txt
:
project(QWidgetBackgroundImage)
cmake_minimum_required(VERSION 3.10.0)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
find_package(Qt5Widgets CONFIG REQUIRED)
include_directories("${CMAKE_SOURCE_DIR}")
add_executable(testQWidgetBackgroundImage testQWidgetBackgroundImage.cc)
target_link_libraries(testQWidgetBackgroundImage Qt5::Widgets)
输出:
因此,至少在使用 VS 2017 和 Qt 5.13 的 Windows 10 中,我能够显示带有样式 sheet 背景图像的普通 QWidget
。
这与 Qt Style Sheets Reference – background 中记录的内容一致:
Shorthand notation for setting the background. Equivalent to specifying background-color, background-image, background-repeat, and/or background-position.
This property is supported by QAbstractItemView subclasses, QAbstractSpinBox subclasses, QCheckBox, QComboBox, QDialog, QFrame, QGroupBox, QLabel, QLineEdit, QMenu, QMenuBar, QPushButton, QRadioButton, QSplitter, QTextEdit, QToolTip, and plain QWidgets.
注:
我必须承认我对Qt资源的使用没有任何经验。因此,我提供了 URL 和 url(cat.jpg)
一样,这导致尝试从本地当前工作目录中的文件加载(成功如上面的快照所示)。带有 :
的前缀(例如 url(:/cat.jpg)
)将改为寻址 Qt 资源中的条目。
进一步阅读:The Qt Resource System
阅读文档后。在上面的 link 中,我注意到使用起来并没有那么复杂,并对上面的 MCVE 进行了一些修改:
C++ 源文件 testQWidgetBackgroundImage.cc
// Qt header:
#include <QtWidgets>
// main application
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// setup GUI
QWidget qWinMain;
qWinMain.setWindowTitle("Test Background Image");
qWinMain.resize(640, 480);
qWinMain.setObjectName("Widget");
qWinMain.setStyleSheet("#Widget { background-image: url(:/cat.jpg); }");
qWinMain.show();
// runtime loop
return app.exec();
}
实际上,唯一的变化是 url(cat.jpg)
→ url(:/cat.jpg)
。
Qt 资源文件testQWidgetBackgroundImage.qrc
:
<!DOCTYPE RCC>
<RCC version="1.0">
<qresource>
<file>cat.jpg</file>
</qresource>
</RCC>
Qt 工程文件testQWidgetBackgroundImage.pro
:
SOURCES = testQWidgetBackgroundImage.cc
RESOURCES = testQWidgetBackgroundImage.qrc
QT += widgets
在 cygwin64 中构建并测试:
$ qmake-qt5 testQWidgetBackgroundImage.pro
$ make && ./testQWidgetBackgroundImage
g++ -c -fno-keep-inline-dllexport -D_GNU_SOURCE -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtWidgets -isystem /usr/include/qt5/QtGui -isystem /usr/include/qt5/QtCore -I. -I/usr/lib/qt5/mkspecs/cygwin-g++ -o testQWidgetBackgroundImage.o testQWidgetBackgroundImage.cc
/usr/lib/qt5/bin/rcc -name testQWidgetBackgroundImage testQWidgetBackgroundImage.qrc -o qrc_testQWidgetBackgroundImage.cpp
g++ -c -fno-keep-inline-dllexport -D_GNU_SOURCE -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtWidgets -isystem /usr/include/qt5/QtGui -isystem /usr/include/qt5/QtCore -I. -I/usr/lib/qt5/mkspecs/cygwin-g++ -o qrc_testQWidgetBackgroundImage.o qrc_testQWidgetBackgroundImage.cpp
g++ -o testQWidgetBackgroundImage.exe testQWidgetBackgroundImage.o qrc_testQWidgetBackgroundImage.o -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread
Qt Version: 5.9.4
输出: