文章目录
- 一、代码中QMessageBox出现中文,运行时会乱码
- 二、条形文本框和文本框获取内容的方法
- 三、如何获得一些特殊路径
- 四、选择文件路径,读取文件内容
- 五、快速部署
- 六、鼠标事件相关
- 七、颜色选择器
- 八、绘制事件
- 九、进度条
- 十、信号槽的格式
- 十一、打开指定路径下的文件
- 十二、关闭程序
- 十三、检测后台是否有指定程序正在运行
- 十四、提示弹窗
- 十五、使用代码启动外部程序并传参
- 十六、生成随机数
- 十七、信号槽,lambda表达式与循环调用的问题
- 十七、QPushButton隐藏后的占位问题
- 十八、Qt下拉框设置行高设置不上
- 十九、设置复选框
- 二十、QLabel设置一些样式
- 二十一、设置随机颜色的QLabel背景
- 二十二、图片点击时生成一个放大的图片
- 二十三、Qt单例类
- 二十四、根据路径创建文件夹,可以创建多层
- 二十五、右键菜单,绑定复制和另存为图片两个功能
- 二十六、设置图标(窗口图标和exe图标)
- 二十七、Qt——FTP
- 二十八、读取配置文件
- 二十八、qss样式设置不上的问题
推荐给大家一个QT美化界面的一些Demo 链接
一、代码中QMessageBox出现中文,运行时会乱码
只要在文件头部加一句#pragma execution_character_set("utf-8")
即可
二、条形文本框和文本框获取内容的方法
//获取条形文本框内容
QString text = ui->lineEdit->text();
//以html的方式获取文本框的内容(含格式)
QString strHtml=ui->textEdit->document()->toHtml();
//以纯文本的方式获取文本框的内容(不含格式)
QString strText=ui->textEdit->document()->toPlainText();
三、如何获得一些特殊路径
比如程序在F:\test\QTtest\x64\Debug\test.exe
// 获得可执行文件所在路径 F:\test\QTtest\x64\Debug
qDebug() << QCoreApplication::applicationDirPath();
// 获得可执行文件全路径 F:\test\QTtest\x64\Debug\test.exe`
qDebug() << qApp->applicationFilePath();
// 获得当前工作目录 F:\test\QTtest
qDebug() << QDir::currentPath();
// 获得用户目录路径 C:/Users/Administrato
qDebug() << QStandardPaths::writableLocation(QStandardPaths::HomeLocation);
qDebug() << QDir::homePath();
// 获得桌面路径 C:/Users/Administrator/Desktop
qDebug() << QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
四、选择文件路径,读取文件内容
QString fileName = QFileDialog::getOpenFileName(this, "选择文件", "", "文件(*.txt)");
//"选择文件"是弹窗的标题,后面一个空的参数是打开时的默认路径,最后一个参数是选择的文件类型
if (!fileName.isEmpty()) {
QFile file(fileName);
file.open(QFile::ReadOnly | QIODevice::Text);
QString codetxt = file.readAll(); //读取文件内容
file.close(); //一定要记得关闭文件,不然会出现奇怪的错误
ui->textEdit->clear();
ui->textEdit->insertPlainText(QString(codetxt));
}
QString selectedDir = QFileDialog::getExistingDirectory(this, "选择文件夹", "", QFileDialog::ShowDirsOnly);
//选择文件夹,弹窗标题,默认打开路径
if (!selectedDir.isEmpty()) {
qDebug() << selectedDir;
}
五、快速部署
1.把可执行文件单独放到一个文件夹中
2.找到QT对应版本的MSVC并打开
3.输入windeployqt.exe 路径名(注意不要出现中文),双击回车
4.然后程序依赖的所有QT库就都包含在里面啦,但是特殊的依赖项还需要自己手动添加
六、鼠标事件相关
#include <QMouseEvent>
void mousePressEvent(QMouseEvent *event)override; // 鼠标单击事件
void mouseMoveEvent(QMouseEvent *event)override; // 鼠标移动事件
void mouseReleaseEvent(QMouseEvent *event)override; // 鼠标释放事件
void mouseDoubleClickEvent(QMouseEvent *event)override; // 鼠标双击事件
void enterEvent(QEvent* event)override; // 鼠标进入事件
void leaveEvent(QEvent* event)override; // 鼠标离开事件
鼠标移动事件有个问题,就是默认单击按键之后才会进入移动事件,如果需要持续跟踪鼠标状态需要提前设置
this->setMouseTracking(true);//持续捕捉鼠标事件,不用按下鼠标也可以捕捉到;
动态绘制的时候,要在移动事件里加
在事件函数里可以获取鼠标位置
QPoint p_ab = event->globalPos();//相对于整个桌面的位置
QPoint p_re = event->pos();//相对于Widget窗口内的位置
通过判断语句区分触发事件的鼠标类型
if(event->button() & Qt::LeftButton){}
else if(event->button() & Qt::RightButton){}
设置鼠标指形状
this->setCursor(Qt::ArrowCursor);
Qt::ArrowCursor //标准箭头
Qt::CrossCursor //空心十字
Qt::PointingHandCursor //指示手型
Qt::OpenHandCursor //展开手掌
Qt::ClosedHandCursor //握紧手掌
七、颜色选择器
static QColor getColor(const QColor &initial = Qt::white, //打开时的默认颜色
QWidget *parent = nullptr, //父类
const QString &title = QString(), //弹窗标题
ColorDialogOptions options = ColorDialogOptions());
QColorDialog::ShowAlphaChannel 允许用户设置颜色的透明度
QColorDialog::NoButtons 不显示OK和Cancel按钮
QColorDialog::DontUseNativeDialog 使用Qt标准颜色对话框,而不是操作系统本地颜色对话框。
如果默认颜色设置的是纯黑,那么在右侧颜色栏里选择颜色,并不会生效
,因为如下图所示的部分拉到底了,换什么颜色都是黑的
八、绘制事件
void paintEvent(QPaintEvent* event) override;
画东西的操作都要在绘制事件内执行
QPainter* painter;
painter = new QPainter(this);
painter->setRenderHint(QPainter::Antialiasing, true);//抗锯齿
painter->setPen(QColor());
painter->drawLine(QPoint(),QPoint()); //画线
painter->drawRect(QRect(QPoint(),QPoint())); //对角线画矩形
painter->drawEllipse(QRect(QPoint(),QPoint())); //对角线矩形的四边中点连接圆
//画正圆
float radius = qSqrt(qPow(it->beginPoint.x() - it->tempPoint.x(), 2) + qPow(it->beginPoint.y() - it->tempPoint.y(), 2)) / 2;
QPoint midle = QPoint((it->beginPoint.x() + it->tempPoint.x()) / 2, (it->beginPoint.y() + it->tempPoint.y()) / 2);
QPoint LeftTop = QPoint(midle.x() - radius, midle.y() - radius);
QPoint RightBottom = QPoint(midle.x() + radius, midle.y() + radius);
painter->drawEllipse(QRect(LeftTop, RightBottom));
九、进度条
#include <QProgressDialog>
QProgressDialog* progressDialog = nullptr;
progressDialog = new QProgressDialog();
progressDialog->setWindowModality(Qt::WindowModal);
progressDialog->setMinimumDuration(5);
progressDialog->setLabelText("正在下载平台更新资源"); //设计进度条对话框中标签的文字
progressDialog->setCancelButton(nullptr);
progressDialog->setWindowFlags(Qt::Dialog | Qt::FramelessWindowHint);
progressDialog->setRange(0, 100);
progressDialog->setValue(20);
十、信号槽的格式
// connect(指针,&类名::函数名,指针,&类名::函数名)
QObject::connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
// connect(指针,&SIGNAL(函数名(参数列表)),指针,&SLOT(函数名(参数列表)))
QObject::connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(slotDownLoadSpeed(qint64, qint64)));
// connect(指针,&类名::函数名,Lamble表达式)
QObject::connect(reply, &QNetworkReply::readyRead, [&]() {
QByteArray bytes = reply->readAll();
tempFile->write(bytes);
tempFile->flush();
});
注意!!!!所有加类名的地方只能写一层,不可以写成 类名::类名::函数名
信号槽里的参数列表只写变量类型就好,不要加形参!
十一、打开指定路径下的文件
QString strPicPath = savePath; //要打开的文件路径
strPicPath.replace("/", "\\"); //win32下替换斜杠
QProcess process;
process.startDetached("explorer", QStringList() << QString("/select,") << QString("%1").arg(strPicPath));
十二、关闭程序
通过关联信号槽实现关闭程序
//关联槽函数quit(),qApp是一个宏
QObject::connect(this, SIGNAL(signalQuit()), qApp, SLOT(quit()));
或者直接调用函数qApp->exit(0)
或qApp->quit()
另外,在构造函数里调用这些代码是没有作用的
如果希望在构造函数里做一些判断,不符合判断的直接退出关闭程序
可以单独写一个返回值为bool类型的函数,在main函数里放在show函数前调用
或者exit(-1);
十三、检测后台是否有指定程序正在运行
bool CheckAppRunningStatus(const QString& appName) {
#ifdef Q_OS_WIN //表示如果在windows下
QProcess* process = new QProcess;
process->start("tasklist", QStringList() << "/FI" << "imagename eq " + appName);
process->waitForFinished();
QString outputStr = QString::fromLocal8Bit(process->readAllStandardOutput());
process->close();
delete process;
return outputStr.contains(appName);
#endif
}
void KillAppProcess(const QString& appName) {
QProcess process;
QString command = "taskkill /im " + appName + " /f";
process.execute(command);
//execute执行后会一直阻塞到返回外部程序退出的代码,比如无法关闭会返回-2
process.close();
}
//调用示例
CheckAppRunningStatus("program.exe");
KillAppProcess("program.exe");
十四、提示弹窗
QMessageBox MyBox(QMessageBox::Question, "", "");
MyBox.setParent(this);
//设置消息框的属性为对话框,它会是一个独立的窗口
MyBox.setWindowFlags(Qt::Dialog);
MyBox.setWindowTitle("提示");
MyBox.setText("更新内容已下载完成,是否立即更新");
//自定义两个按钮
QPushButton* agreeBut = MyBox.addButton("立即更新", QMessageBox::AcceptRole);
QPushButton* disagreeBut = MyBox.addButton("稍后更新", QMessageBox::RejectRole);
MyBox.show();
//添加信号和槽,监听用户点击的按钮
QObject::connect(agreeBut, &QPushButton::clicked, this, &Program::Clicked);
QObject::connect(disagreeBut, &QPushButton::clicked, [&]() {
MyBox.close();
});
MyBox.exec();
十五、使用代码启动外部程序并传参
调用程序的代码
QString str;
int a;
//第一个参数是要启动的程序的全路径
//第二个参数是字符串数组,用来给启动的程序传递参数,传递的时候以字符串的形式输入到数组中,然后外部程序按需要去解析字符串
QProcess::startDetached("F:/game/steam/It Takes Two.exe",QStringList()<<str<<QString::number(a));
被调用程序的main()函数代码
// argc——argv里的参数个数,如果外部不传参的话,argc=1
// argv——外部传递的参数,argv[0]为程序的全路径,数组后面的值即为外部传进来的参数
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QString str = argv[1];
int num = argv[2].toInt();
return a.exec();
}
十六、生成随机数
网上生成随机数的方法一般是用int rand(void);
函数,但是这种属于为随机数,是系统根据不同的种子生成的,系统默认种子是1,所以说每次使用的随机序列都是固定的。
然后网上就教了void srand(unsigned int seed);
函数,他可以设置rand()
函数的种子,一般用时间作为种子
srand((unsigned)time(NULL));
int x = rand();
cout << "x: " << x << endl;
这种方法保证了每次运行事变量x都会有不同的结果,但是会出现一个问题,如果短时间调用多次rand()
函数,比如:
srand((unsigned)time(NULL));
for(int i = 0 ; i < 10000 ; i++){
int x = rand();
cout << "x: " << x << endl;
}
这时候由于time()
函数会返回1970年1月1日至今所经历的时间(以秒为单位),所以在一秒之内,结果都是固定的,会导致同一秒内生成的随机数相同,这时候我的解决办法是,给srand()
传一个变量
for(unsigned int i = 0 ; i < 10000 ; i++){
srand(i);
int x = rand();
cout << "x: " << x << endl;
}
这样可以解决在短时间内生成大量随机数的需求
或者使用全局随机数生成器
// 获取全局的随机数生成器
QRandomGenerator *generator = QRandomGenerator::global();
// 生成范围在0到360之间的随机数
int randomNumber = generator->bounded(0, 361);
十七、信号槽,lambda表达式与循环调用的问题
工作用遇到这样一个需求,大概是这样
有一个页面里面有n个按钮,最后一个按钮是“增加”,其余每个按钮单击时会被删除
按钮是按顺序排的,所以我设计的就是每次有增加和删除操作的时候,都重新渲染一遍界面
一开始我就在程序初始化的init()
函数里第一次渲染,然后设置那些按钮的绑定事件,这里我直接使用的Lambda表达式
void init(){
…………//一些操作
connect(btns[i], &QPushButton::clicked, [=] {
btns[i]->setText("按钮1");
…………//一些操作
init();
)};
}
btns是一个全局变量的数组,但是这样写有一个问题就是i
不会被传递,触发点击事件的时候,i
早就离开作用域了
然后我就auto temp = btns[i]
,但是这样依然不可以,
后来觉得可能是lambda表达式的问题,因为我一旦执行到刷新界面的init()
函数,我就会取消之前按钮设置的所有事件,那这样的话这个信号槽就不存在了,但是lambda表达式需要执行完init()
函数才能结束。也就是说我在槽函数还没执行完的时候就把信号槽抹去了
最后改成了点击事件绑定另外一个函数,终于跑通了
总结起来,Lambda表达式使用时要慎重呀
在这贴一个表格里的一个单元格插入“修改”和“删除”两个按钮的代码
QWidget* pWidget = new QWidget(表格的wid); //创建一个widget
QHBoxLayout* hLayout = new QHBoxLayout(pWidget); //创建布局
QPushButton* reviseBtn = new QPushButton(pWidget);
QPushButton* deleteBtn = new QPushButton(pWidget);
//根据objectName ,去拆解所属的tableWidget 、行、列
reviseBtn->setStyleSheet(修改按钮的样式);
reviseBtn->setText("修 改");
reviseBtn->setObjectName(QString("%1_%2_reviseBtn").arg(表格的wid->objectName()).arg(_row));
reviseBtn->setFont(表格的wid->font());
deleteBtn->setStyleSheet(删除按钮的样式);
deleteBtn->setText("删 除");
deleteBtn->setObjectName(QString("%1_%2_deleteBtn").arg(表格的wid->objectName()).arg(_row));
deleteBtn->setFont(表格的wid->font());
hLayout->addWidget(reviseBtn); //添加
hLayout->addWidget(deleteBtn); //添加
hLayout->setMargin(10); //设置边缘距离
//hLayout->setAlignment(reviseBtn, Qt::AlignCenter); //居中
hLayout->setSpacing(10);
pWidget->setLayout(hLayout); //设置widget的布局
DMTableWid->setCellWidget(_row, j, pWidget);
QPushButton::connect(reviseBtn, &QPushButton::clicked, [=] {
QString objectName = reviseBtn->objectName();
QStringList nameList = objectName.split("_");//拆解
if (nameList.count() == 3) {
int tempRow = nameList.at(1).toInt();//行
……//修改的操作
}
});
QPushButton::connect(deleteBtn, &QPushButton::clicked, [=] {
QString objectName = deleteBtn->objectName();
QStringList nameList = objectName.split("_");//拆解
if (nameList.count() == 3) {
int tempRow = nameList.at(1).toInt();//行
QMessageBox MyBox(QMessageBox::Information, "", "");
MyBox.setParent(this);
//设置消息框的属性为对话框,它会是一个独立的窗口
MyBox.setWindowFlags(Qt::Dialog);
MyBox.setWindowTitle("提示");
MyBox.setText("是否要删除这条数据?\n提示:连同数据库中的内容将一并被删除!");
//自定义两个按钮
QPushButton* agreeBut = MyBox.addButton("确认删除", QMessageBox::AcceptRole);
QPushButton* disagreeBut = MyBox.addButton("考虑一下", QMessageBox::RejectRole);
MyBox.show();
//添加信号和槽,监听用户点击的按钮
QObject::connect(agreeBut, &QPushButton::clicked, [&] {
demandVer.removeAt(tempRow);
表格的wid.insert(tempRow+1);
update(0);
});
QObject::connect(disagreeBut, &QPushButton::clicked, [&]() {
MyBox.close();
});
MyBox.exec();
}
});
十七、QPushButton隐藏后的占位问题
正常情况下hide()
函数能够隐藏按钮,但是父节点有布局的话,隐藏之后其他的控件就会挤占该按钮的位置,如果不希望按钮被隐藏时占位取消的话可以用下面这种方法
btn->hide();
QSizePolicy sp_retain = btn->sizePolicy();
sp_retain.setRetainSizeWhenHidden(true);
btn->setSizePolicy(sp_retain);
十八、Qt下拉框设置行高设置不上
在添加下拉框的QStringList的时候加一句话就好了ui.choosebox->setView(new QListView());
十九、设置复选框
QWidget *pWidget = new QWidget(父节点); //创建一个widget
QHBoxLayout* hLayout = new QHBoxLayout(pWidget); //创建布局
QCheckBox *pCheckBox = new QCheckBox(pWidget);
//根据objectName ,去拆解所属的tableWidget 、行、列
pCheckBox->setObjectName(QString("%1_%2_Itme").arg(tableWid->objectName()).arg(row));
pCheckBox->setChecked(false);
QFont m_font;//通过设置字体大小,来改变复选框的大小
pCheckBox->setFont(m_font);
pCheckBox->setFocusPolicy(Qt::NoFocus);
pCheckBox->setStyle(QStyleFactory::create("fusion"));
pCheckBox->setStyleSheet(QString(".QCheckBox {margin:3px;border:0px;}QCheck6Box::indicator {width: %1px; height: %1px; }").arg(20));
hLayout->addWidget(pCheckBox); //添加
hLayout->setMargin(0); //设置边缘距离
hLayout->setAlignment(pCheckBox, Qt::AlignCenter); //居中
hLayout->setSpacing(0);
pWidget->setLayout(hLayout); //设置widget的布局
QCheckBox::connect(pCheckBox, &QCheckBox::stateChanged, [=] {
QString objectName = pCheckBox->objectName();
QStringList nameList = objectName.split("_");//拆解
if (nameList.count() == 3)
{
QString tableName = nameList.at(0);//表格名称
int _row = nameList.at(1).toInt();//行
bool checked = pCheckBox->isChecked();//是否被选中
······
二十、QLabel设置一些样式
QLabel *my_lab = new QLabel();
// 设置文字可以复制
my_lab->setTextInteractionFlags(Qt::TextSelectableByMouse);
// 设置文字居中
my_lab->setAlignment(Qt::AlignCenter);
// 设置文字首行缩进
QString contents = "<p style=\"text-indent: 20px;margin-bottom: 1px;margin-top: 1px;\">" + 你的文字 + "</p>";
my_lab->setText(contents);
// 如果有多段文字的设置首行缩进
QString contents = "";
QStringList p_content = 你的文字.split('\n');
for (size_t i = 0; i < p_content.size(); i++)
{
contents = contents + "<p style=\"text-indent: 20px;margin-bottom: 1px;margin-top: 1px;\">" + p_content[i] + "</p>";
}
my_lab->setText(contents);
// 在Label中加载图片
QString imgPath = "图片路径";
if (QFile::exists(imgPath)) {
// 图像文件存在,继续加载图像
QImage img(imgPath);
QPixmap pixmap = QPixmap::fromImage(img);
// 进行缩放和显示等操作
QPixmap fitPixmap = pixmap.scaled(imgLab->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation);
imgLab->setScaledContents(true);
imgLab->setPixmap(fitPixmap);
}
else {
// 图像文件不存在,处理加载失败的情况
qDebug() << "图片文件不存在" << imgPath;
}
二十一、设置随机颜色的QLabel背景
int red = rand() % 256;
int green = rand() % 256;
int blue = rand() % 256;
while (qAbs(red - green) <= 30 && qAbs(green - blue) <= 30 && qAbs(blue - red) <= 30) {
red = rand() % 256;
green = rand() % 256;
blue = rand() % 256;
}
QString color1 = QString("rgba(%1,%2,%3,0.2)").arg(red).arg(green).arg(blue);
QString style = QString(
"QLabel{"
"font-family: \"黑体\", sans-serif;"
"font-size: 13px;"
"padding-top: 3px;"
"padding-bottom: 3px;"
"background: %1;"
"border: none;"
"border-radius: 7px;"
"}").arg(color1);
二十二、图片点击时生成一个放大的图片
#include <QMouseEvent>
public:
bool eventFilter(QObject* obj, QEvent* event); // 添加时间过滤器声明
bool :eventFilter(QObject* obj, QEvent* event)
{
if (obj->objectName().contains("你给控件做的特殊标记"))//指定某个QLabel
{
if (event->type() == QEvent::MouseButtonPress) //鼠标点击
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event); // 事件转换
if (mouseEvent->button() == Qt::LeftButton)
{
QString m_imgPath = "你的图片路径";
QWidget* bigPic = new QWidget(this);
bigPic->setWindowFlags(windowFlags() & ~Qt::WindowMaximizeButtonHint); // 禁止最大化按钮
bigPic->setFixedSize(500, 500); // 禁止拖动窗口大小
// 设置背景图片
bigPic->setAutoFillBackground(true); // 这句要加上, 否则可能显示不出背景图.
QPalette palette = this->palette();
palette.setBrush(QPalette::Window,
QBrush(QPixmap(m_imgPath).scaled( // 缩放背景图.
bigPic->size(),
Qt::IgnoreAspectRatio,
Qt::SmoothTransformation))); // 使用平滑的缩放方式
bigPic->setPalette(palette);
bigPic->show();
bigPic->setWindowTitle("图片详情");
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
else
{
// pass the event on to the parent class
return QWidget::eventFilter(obj, event);
}
}
二十三、Qt单例类
class PubVariable : public QObject
{
Q_OBJECT
public:
//获取单例实例的静态函数
static PubVariable* getInstance();
signals:
// 定义你的信号
private:
// 私有构造函数和析构函数,以确保不能直接实例化或销毁对象
explicit PubVariable(QObject* parent = nullptr);
~PubVariable();
// 防止复制和赋值操作
PubVariable(const PubVariable&) = delete;
PubVariable& operator=(const PubVariable&) = delete;
// 单例实例
static PubVariable* instance;
// 其他私有成员变量
······
}
// 初始化静态成员变量
PubVariable* PubVariable::instance = nullptr;
PubVariable* PubVariable::getInstance()
{
if (instance == nullptr)
{
// 如果实例不存在,创建一个新实例
instance = new PubVariable();
}
return instance;
}
二十四、根据路径创建文件夹,可以创建多层
QString mkMutiDir(const QString path)
{
QDir dir(path);
if (dir.exists(path)) {
return path;
}
QString parentDir = mkMutiDir(path.mid(0, path.lastIndexOf('/')));
QString dirname = path.mid(path.lastIndexOf('/') + 1);
QDir parentPath(parentDir);
if (!dirname.isEmpty())
parentPath.mkpath(dirname);
return parentDir + "/" + dirname;
}
二十五、右键菜单,绑定复制和另存为图片两个功能
bool DetailPage::eventFilter(QObject* obj, QEvent* event)
{
if (obj->objectName().contains("EVENT"))//指定某个QLabel
{
if (event->type() == QEvent::MouseButtonPress) //鼠标点击
{
QMouseEvent* mouseEvent = static_cast<QMouseEvent*>(event); // 事件转换
if (mouseEvent->button() == Qt::RightButton) {
QPoint globalPos = mouseEvent->globalPos(); // 获取全局坐标
QPoint widgetPos = mapFromGlobal(globalPos);
QMenu contextMenu(this);
QAction* copyAction = contextMenu.addAction("复制");
QAction* saveAction = contextMenu.addAction("另存为");
connect(copyAction, &QAction::triggered, [=]() {
QString m_imgPath = obj->objectName().split("EVENT").at(0);
m_imgPath = "你的图片路径";
QPixmap pixmap(m_imgPath);
QClipboard* clipboard = QApplication::clipboard();
clipboard->setPixmap(pixmap);
});
connect(saveAction, &QAction::triggered, [=]() {
QString filePath = QFileDialog::getSaveFileName(this, "另存为", QDir::homePath(), "Images (*.png *.jpg *.bmp)");
if (!filePath.isEmpty()) {
QString m_imgPath = obj->objectName().split("EVENT").at(0);
m_imgPath = "img/" + QString::number(thisDemand.TimeTab) + "/" + m_imgPath;
QPixmap pixmap(m_imgPath);
pixmap.save(filePath);
}
});
contextMenu.exec(mapToGlobal(globalPos));
}
else
{
return false;
}
}
else
{
return false;
}
}
else
{
// pass the event on to the parent class
return QWidget::eventFilter(obj, event);
}
}
二十六、设置图标(窗口图标和exe图标)
this->setWindowIcon(QIcon("logo.png"));//设置窗口图标
1.在网站上将图片转换成.ico格式(例如:logo.ico);
2.在工程根目录下,新建一个logo.rc文件,文件里写下:
IDI_ICON1 ICON DISCARDABLE "logo.ico"
3.在工程根目录下,找到.vcxproj文件,在:
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
之后,添加
<ItemGroup>
<ResourceCompile Include="logo.rc" />
</ItemGroup>
然后重新生成项目即可。
二十七、Qt——FTP
使用的时候要自己加信号槽,得到信号之后再进行下一步
比如:
QTimer timer;
timer.setInterval(1000);
timer.setSingleShot(true);
FTP* manager = new FTP(F_IP, F_UserName, F_PassWord, 21);
QEventLoop loop;
QObject::connect(&_timer, &QTimer::timeout, &_loop, &QEventLoop::quit);
QObject::connect(manager, &FTP::logInSuccess, [&](bool a) { _loop.quit(); });
timer.start();
loop.exec();
if (timer.isActive()) {timer.stop();}
二十八、读取配置文件
QString filePath = QCoreApplication::applicationDirPath() + "\\config.cfg";
QFile file(filePath);
file.open(QFile::ReadOnly | QIODevice::Text);
QString codetxt = file.readAll(); //读取文件内容
file.close(); //一定要记得关闭文件,不然会出现奇怪的错误
QStringList arr1 = codetxt.split("\n");
for (size_t i = 0; i < arr1.size(); i++)
{
QString temp = arr1.at(i);
if (temp.contains('=')) {
QStringList infor = temp.split('=');
if (infor.size() != 2)continue;
QString name = infor.at(0).trimmed();
QString value = infor.at(1).trimmed();
if (name.contains("ip")) {
IP = value;
}
else if (name.contains("port")) {
Port = value;
}
}
}
qDebug() << "IP:" << IP;
qDebug() << "Port:" << Port;
config.cfg,配置文件里的内容
[server_config]
ip=192.168.10.10
port=91
二十八、qss样式设置不上的问题
可以通过在构造函数内重新加载一遍qss文件
QString style("../Styles/QSS/qt_default_style_sheet.qss");
QFile qss(QDir(style).absolutePath());
if (qss.open(QFile::ReadOnly))
{
setStyleSheet(qss.readAll());
qss.close();
}
在工作中发现如果有切换样式的需求,比如
if (borderVisible) {
label->setProperty("class", "labelWithoutBorder");
label->setText("Label without Border");
} else {
label->setProperty("class", "labelWithBorder");
label->setText("Label with Border");
}
borderVisible = !borderVisible;
根据不同的情景切换level,有时会切换不了,此时可以强制卸载样式再重新加载
// 强制 Qt 重新应用样式
label->style()->unpolish(label);
label->style()->polish(label);
提示:未完待续……