QT日常记录的一些小知识


推荐给大家一个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);

提示:未完待续……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值