当前位置: 首页 > news >正文

QT基本对话框(基本对话框、工具盒类、进度条、调色板与电子钟、可扩展对话框、程序启动画面)

此篇文章通过实例介绍基本对话框的用法。首先介绍标准文件对话框(QFileDialog)、标准颜色对话框(QColorDialog)、标准字体对话框(QFontDialog)、标准输入对话框(QInputDialog)以及标准消息对话框(QMessageBox)。
文章后面将介绍QToolBox类的使用、进度条的用法、QPalette类的用法、QTime类的用法、mousePressEvent/mouseMoveEvent类的用法、可扩展对话框的基本实现方法、不规则窗体的实现及程序启动画面(QSplashScreen)的使用。

基本对话框

创建一个DialogExample工程,在工程项目种实现基本对话框功能。界面UI布局效果如下图:
在这里插入图片描述界面布局代码如下:

Dialog::Dialog(QWidget *parent): QDialog(parent)
{setWindowTitle(QStringLiteral("各种标准对话框的实例"));fileBtn=new QPushButton;                                    //各个控件对象的初始化fileBtn->setText(QStringLiteral("文件标准对话框实例"));fileLineEdit=new QLineEdit;                                 //用来显示选择的文件名mainLayout=new QGridLayout(this);                           //布局设计mainLayout->addWidget(fileBtn,0,0);mainLayout->addWidget(fileLineEdit,0,1);connect(fileBtn,SIGNAL(clicked()),this,SLOT(showFile()));   //事件关联colorBtn=new QPushButton;                                   //创建各个控件的对象colorBtn->setText(QStringLiteral("颜色标准对话框实例"));colorFrame=new QFrame;colorFrame->setFrameShape(QFrame::Box);colorFrame->setAutoFillBackground(true);mainLayout->addWidget(colorBtn,1,0);                        //布局设计mainLayout->addWidget(colorFrame,1,1);connect(colorBtn,SIGNAL(clicked()),this,SLOT(showColor())); //事件关联fontBtn=new QPushButton;                                    //创建控件的对象fontBtn->setText(QStringLiteral("字体标准对话框实例"));fontLineEdit=new QLineEdit;                                 //显示更改的字符串fontLineEdit->setText(tr("Welcome!"));mainLayout->addWidget(fontBtn,2,0);                         //布局设计mainLayout->addWidget(fontLineEdit,2,1);connect(fontBtn,SIGNAL(clicked()),this,SLOT(showFont()));	//事件关联inputBtn=new QPushButton;                                   //创建控件的对象inputBtn->setText(QStringLiteral("标准输入对话框实例"));mainLayout->addWidget(inputBtn,3,0);                        //布局设计connect(inputBtn,SIGNAL(clicked()),this,SLOT(showInputDlg()));//事件关联MsgBtn =new QPushButton;                                    //创建控件对象MsgBtn->setText(QStringLiteral("标准消息对话框实例"));mainLayout->addWidget(MsgBtn,3,1);connect(MsgBtn,SIGNAL(clicked()),this,SLOT(showMsgDlg()));CustomBtn =new QPushButton;CustomBtn->setText(QStringLiteral("用户自定义消息对话框实例"));label =new QLabel;label->setFrameStyle(QFrame::Panel|QFrame::Sunken);mainLayout->addWidget(CustomBtn,4,0);mainLayout->addWidget(label,4,1);connect(CustomBtn,SIGNAL(clicked()),this,SLOT(showCustomDlg()));
}

文件标准对话框

点击“文件标准对话框实例”按钮,弹出“文件选择”对话框如下图所示。
在这里插入图片描述
界面功能实现代码如下:

void Dialog::showFile()
{QString s = QFileDialog::getOpenFileName(this,"open file dialog","/","C++ files(*.cpp);;C files(*.c);;Head files(*.h)");fileLineEdit->setText(s);
}

QFileDialog::getOpenFileName函数说明如下:

QString QFileDialog::getOpenFileName
(QWidget *parent = nullptr, 					// 标准文件对话框的父窗口const QString &caption = QString(), 		// 标准文件对话框的标题名const QString &dir = QString(), 			// 指定默认的目录,若此参数带有文件名,则文件将是默认选中的文件const QString &filter = QString(), 			// 此参数对文件类型进行过滤,只有与之过滤器匹配的的文件类型才显示,可以同时指定多种过滤方式供用户选择,多种过滤器之间用“;;”隔开。QString *selectedFilter = nullptr, 			// 用户选择的过滤器通过此参数返回QFileDialog::Options options = Options()	// 选择显示文件名的格式,默认是同时显示目录与文件名
)

颜色标准对话框

点击“颜色标准对话框实例”按钮,弹出“颜色选择”对话框,如下图所示。
在这里插入图片描述
界面功能实现代码如下:

void Dialog::showColor()
{QColor c = QColorDialog::getColor(Qt::blue);if(c.isValid()){colorFrame->setPalette(QPalette(c));}
}

QColorDialog::getColor函数说明如下:

QColor QColorDialog::getColor
(const QColor &initial = Qt::white, 	// 指定默认选中的颜色,默认白色。通过QColor::isValid()函数可以判断用户选择的颜色是否有效,如果用户选择颜色时点击“取消”,则QColor::isValid()函数将返回false。QWidget *parent = nullptr, 			// 标准颜色对话框的父窗口const QString &title = QString(), QColorDialog::ColorDialogOptions options = ColorDialogOptions()
)

字体标准对话框

点击“字体标准对话框实例”按钮,弹出“字体选择”对话框,如下图所示。
在这里插入图片描述
界面功能实现代码如下:

void Dialog::showFont()
{bool ok;QFont f = QFontDialog::getFont(&ok);if (ok){fontLineEdit->setFont(f);}
}

QFontDialog::getFont函数说明如下:

QFont QFontDialog::getFont(bool *ok, 					// 若用户点“OK”按钮,则该参数*ok将设为true,函数返回用户所选择的字体;否则,将设为false,此时函数返回默认字体QWidget *parent = nullptr	// 标准字体对话框的父窗口
)

标准输入对话框

标准输入对话框包括:标准字符串输入对话框、标准条目选择对话框、标准int类型输入对话框和标准double类型输入对话框。
点击“标准输入对话框实例”按钮,,弹出“标准输入对话框实例”页面,如下图所示。
在这里插入图片描述
界面功能实现代码如下:

void Dialog::showInputDlg()
{inputDlg =new InputDlg(this);inputDlg->show();
}

InputDlg类界面布局如下:

InputDlg::InputDlg(QWidget* parent):QDialog(parent)
{setWindowTitle(QStringLiteral("标准输入对话框实例"));nameLabel1 =new QLabel;nameLabel1->setText(QStringLiteral("姓名:"));nameLabel2 =new QLabel;nameLabel2->setText(QStringLiteral("周何骏"));              		//姓名的初始值nameLabel2->setFrameStyle(QFrame::Panel|QFrame::Sunken);nameBtn =new QPushButton;nameBtn->setText(QStringLiteral("修改姓名"));sexLabel1 =new QLabel;sexLabel1->setText(QStringLiteral("性别:"));sexLabel2 =new QLabel;sexLabel2->setText(QStringLiteral("男"));                		//性别的初始值sexLabel2->setFrameStyle(QFrame::Panel|QFrame::Sunken);sexBtn =new QPushButton;sexBtn->setText(QStringLiteral("修改性别"));ageLabel1 =new QLabel;ageLabel1->setText(QStringLiteral("年龄:"));ageLabel2 =new QLabel;ageLabel2->setText(QStringLiteral("21"));           			//年龄的初始值ageLabel2->setFrameStyle(QFrame::Panel|QFrame::Sunken);ageBtn =new QPushButton;ageBtn->setText(QStringLiteral("修改年龄"));scoreLabel1 =new QLabel;scoreLabel1->setText(QStringLiteral("成绩:"));scoreLabel2 =new QLabel;scoreLabel2->setText(QStringLiteral("80"));         			//成绩的初始值scoreLabel2->setFrameStyle(QFrame::Panel|QFrame::Sunken);scoreBtn =new QPushButton;scoreBtn->setText(QStringLiteral("修改成绩"));mainLayout =new QGridLayout(this);mainLayout->addWidget(nameLabel1,0,0);mainLayout->addWidget(nameLabel2,0,1);mainLayout->addWidget(nameBtn,0,2);mainLayout->addWidget(sexLabel1,1,0);mainLayout->addWidget(sexLabel2,1,1);mainLayout->addWidget(sexBtn,1,2);mainLayout->addWidget(ageLabel1,2,0);mainLayout->addWidget(ageLabel2,2,1);mainLayout->addWidget(ageBtn,2,2);mainLayout->addWidget(scoreLabel1,3,0);mainLayout->addWidget(scoreLabel2,3,1);mainLayout->addWidget(scoreBtn,3,2);mainLayout->setMargin(15);mainLayout->setSpacing(10);connect(nameBtn,SIGNAL(clicked()),this,SLOT(ChangeName()));connect(sexBtn,SIGNAL(clicked()),this,SLOT(ChangeSex()));connect(ageBtn,SIGNAL(clicked()),this,SLOT(ChangeAge()));connect(scoreBtn,SIGNAL(clicked()),this,SLOT(ChangeScore()));
}

标准消息对话框

点击“标准消息对话框实例”按钮,弹出“标准消息对话框实例”页面,如下图所示。
在这里插入图片描述
界面功能实现代码如下:

void Dialog::showMsgDlg()
{msgDlg =new MsgBoxDlg();msgDlg->show();
}

MsgBoxDlg类界面布局如下:

MsgBoxDlg::MsgBoxDlg(QWidget *parent):QDialog(parent)
{setWindowTitle(QStringLiteral("标准消息对话框实例"));    	//设置对话框的标题label = new QLabel;label->setText(QStringLiteral("请选择一种消息框"));questionBtn =new QPushButton;questionBtn->setText(QStringLiteral("QuestionMsg"));informationBtn =new QPushButton;informationBtn->setText(QStringLiteral("InformationMsg"));warningBtn =new QPushButton;warningBtn->setText(QStringLiteral("WarningMsg"));criticalBtn =new QPushButton;criticalBtn->setText(QStringLiteral("CriticalMsg"));aboutBtn =new QPushButton;aboutBtn->setText(QStringLiteral("AboutMsg"));aboutQtBtn =new QPushButton;aboutQtBtn->setText(QStringLiteral("AboutQtMsg"));//布局mainLayout =new QGridLayout(this);mainLayout->addWidget(label,0,0,1,2);mainLayout->addWidget(questionBtn,1,0);mainLayout->addWidget(informationBtn,1,1);mainLayout->addWidget(warningBtn,2,0);mainLayout->addWidget(criticalBtn,2,1);mainLayout->addWidget(aboutBtn,3,0);mainLayout->addWidget(aboutQtBtn,3,1);//事件关联connect(questionBtn,SIGNAL(clicked()),this,SLOT(showQuestionMsg()));connect(informationBtn,SIGNAL(clicked()),this,SLOT(showInformationMsg()));connect(warningBtn,SIGNAL(clicked()),this,SLOT(showWarningMsg()));connect(criticalBtn,SIGNAL(clicked()),this,SLOT(showCriticalMsg()));connect(aboutBtn,SIGNAL(clicked()),this,SLOT(showAboutMsg()));connect(aboutQtBtn,SIGNAL(clicked()),this,SLOT(showAboutQtMsg()));
}

question消息框

question消息框效果如下。
在这里插入图片描述
界面功能代码如下:

void MsgBoxDlg::showQuestionMsg()
{label->setText(QStringLiteral("Question Message Box"));switch(QMessageBox::question(this, QStringLiteral("Question消息框"),QStringLiteral("您现在已经修改完成,是否要结束程序?"),QMessageBox::Ok|QMessageBox::Cancel,QMessageBox::Ok)){case QMessageBox::Ok:label->setText("Question button/Ok");break;case QMessageBox::Cancel:label->setText("Question button/Cancel");break;default:break;}return;
}

QMessageBox::question函数说明如下:

QMessageBox::StandardButton QMessageBox::question
(QWidget *parent, 		// 消息框的父窗口指针const QString &title, 	// 消息框的标题框const QString &text, 	// 消息框的文字提示信息QMessageBox::StandardButtons buttons = StandardButtons(Yes | No), // 填写希望在消息框中出现的的按钮,如QMessageBox::Ok、QMessageBox::Close、QMessageBox::Discard等。在实际使用中应该注意按常规成对出现。例如,通常Save与Discard成对出现,而Abort、Retry、Ignore则一起出现。QMessageBox::StandardButton defaultButton = NoButton			  // 默认按钮,即消息框出现时,焦点默认处于哪个按钮上。
)

information消息框

information消息框效果如下。
在这里插入图片描述
界面功能代码如下:

void MsgBoxDlg::showInformationMsg()
{label->setText(tr("Information Message Box"));QMessageBox::information(this, QStringLiteral("Information消息框"), QStringLiteral("这是Information消息框测试,欢迎您!"));return;
}

QMessageBox::information函数说明如下:

QMessageBox::StandardButton QMessageBox::information
(QWidget *parent, 		// 消息框的父窗口指针const QString &title, 	// 消息框的标题栏const QString &text, 	// 消息框的文字提示信息QMessageBox::StandardButtons buttons = Ok, 				// 填写希望在消息框中出现的的按钮,如QMessageBox::Ok、QMessageBox::Close、QMessageBox::Discard等。在实际使用中应该注意按常规成对出现。例如,通常Save与Discard成对出现,而Abort、Retry、Ignore则一起出现。QMessageBox::StandardButton defaultButton = NoButton	// 默认按钮,即消息框出现时,焦点默认处于哪个按钮上。
)

warning消息框

warning消息框效果如下。
在这里插入图片描述
界面功能代码如下:

void MsgBoxDlg::showWarningMsg()
{label->setText(tr("Warning Message Box"));switch(QMessageBox::warning(this, QStringLiteral("Warning消息框"),QStringLiteral("您修改的内容还未保存,是否要保存对文档的修改?"),QMessageBox::Save|QMessageBox::Discard|QMessageBox::Cancel,QMessageBox::Save)){case QMessageBox::Save:label->setText(tr("Warning button/Save"));break;case QMessageBox::Discard:label->setText(tr("Warning button/Discard"));break;case QMessageBox::Cancel:label->setText(tr("Warning button/Cancel"));break;default:break;}return;
}

QMessageBox::warning函数说明如下:

QMessageBox::StandardButton QMessageBox::warning
(QWidget *parent, 		// 消息框的父窗口指针const QString &title, 	// 消息框的标题栏const QString &text, 	// 消息框的文字提示信息QMessageBox::StandardButtons buttons = Ok, 				// 填写希望在消息框中出现的的按钮,如QMessageBox::Ok、QMessageBox::Close、QMessageBox::Discard等。在实际使用中应该注意按常规成对出现。例如,通常Save与Discard成对出现,而Abort、Retry、Ignore则一起出现。QMessageBox::StandardButton defaultButton = NoButton	// 默认按钮,即消息框出现时,焦点默认处于哪个按钮上。
)

critical消息框

critical消息框效果如下。
在这里插入图片描述
界面功能代码如下:

void MsgBoxDlg::showCriticalMsg()
{label->setText(tr("Critical Message Box"));QMessageBox::critical(this, QStringLiteral("Critical消息框"), QStringLiteral("这是一个Critical消息框测试!"));return;
}

QMessageBox::critical函数说明如下:

QMessageBox::StandardButton QMessageBox::critical
(QWidget *parent, 		// 消息框的父窗口指针const QString &title, 	// 消息框的标题栏const QString &text, 	// 消息框的文字提示信息QMessageBox::StandardButtons buttons = Ok, 				// 填写希望在消息框中出现的的按钮,如QMessageBox::Ok、QMessageBox::Close、QMessageBox::Discard等。在实际使用中应该注意按常规成对出现。例如,通常Save与Discard成对出现,而Abort、Retry、Ignore则一起出现。QMessageBox::StandardButton defaultButton = NoButton	// 默认按钮,即消息框出现时,焦点默认处于哪个按钮上。
)

about消息框

about消息框效果如下。
在这里插入图片描述
界面功能代码如下:

void MsgBoxDlg::showAboutMsg()
{label->setText(tr("About Message Box"));QMessageBox::about(this, QStringLiteral("About消息框"), QStringLiteral("这是一个About消息框测试!"));return;
}

QMessageBox::about函数说明如下:

void QMessageBox::about
(QWidget *parent, 		// 消息框的父窗口指针const QString &title, 	// 消息框的标题栏const QString &text		// 消息框的文字提示信息
)

aboutQt消息框

aboutQt消息框效果如下。
在这里插入图片描述
界面功能代码如下:

void MsgBoxDlg::showAboutQtMsg()
{label->setText(tr("About Qt Message Box"));QMessageBox::aboutQt(this, QStringLiteral("About Qt消息框"));return;
}

QMessageBox::aboutQt函数说明如下:

void QMessageBox::aboutQt
(QWidget *parent, 					// 消息框的父窗口指针const QString &title = QString()	// 消息框的标题栏
)

自定义消息框

当标准对话框不能满足我们的使用需求时,Qt可以自定义消息框。自定义消息框可以对消息框的图标、按钮和内容等根据需要进行设定。下面是自定义消息框的效果图。
在这里插入图片描述
界面功能代码如下:

void Dialog::showCustomDlg()
{label->setText(tr("Custom Message Box"));QMessageBox customMsgBox;customMsgBox.setWindowTitle(QStringLiteral("用户自定义消息框"));	//设置消息框的标题QPushButton *yesBtn=customMsgBox.addButton(tr("Yes"),QMessageBox:: ActionRole);QPushButton *noBtn=customMsgBox.addButton(tr("No"),QMessageBox::ActionRole);QPushButton *cancelBtn=customMsgBox.addButton(QMessageBox::Cancel);customMsgBox.setText(QStringLiteral("这是一个用户自定义消息框!"));customMsgBox.setIconPixmap(QPixmap("DialogExample.ico"));	customMsgBox.exec();                                //显示此自定义消息框if(customMsgBox.clickedButton()==yesBtn)label->setText("Custom Message Box/Yes");if(customMsgBox.clickedButton()==noBtn)label->setText("Custom Message Box/No");if(customMsgBox.clickedButton()==cancelBtn)label->setText("Custom Message Box/Cancel");return;
}

关键代码说明如下:

  • QPushButton *yesBtn=customMsgBox.addButton(tr(“Yes”),QMessageBox:: ActionRole):定义消息框所需的按钮,由于QMessageBox::StandardButton只提供一些常用按钮,并不能满足所有应用的需求,故QMessageBox类提供了一个addButton函数来为消息框增加自定义的按钮,addButton函数第一个参数为按钮显示的文字,第二个参数为按钮类型的描述。
  • QPushButton *cancelBtn=customMsgBox.addButton(QMessageBox::Cancel):使用addButton函数加入一个标准按钮。消息框将会按调用addButton函数的先后顺序在消息框中由左至右依次插入按钮。
  • customMsgBox.setText(QStringLiteral(“这是一个用户自定义消息框!”)):设置自定义消息框中显示的提示信息内容。
  • customMsgBox.setIconPixmap(QPixmap(“DialogExample.ico”)):设置自定义消息框的图标。

工具盒类QToolBox

工具盒类QToolBox提供了一种列状的层叠窗体,而QToolButton提供了一种快速访问命令或选择项的按钮在工具条中使用。
下面通过一个MyQQExample项目实现类似QQ抽屉效果的实例介绍QToolBox类的使用,运行效果如下图所示。
在这里插入图片描述
页面布局代码如下:

Drawer::Drawer(QWidget *parent, Qt::WindowFlags f):QToolBox(parent,f)
{setWindowTitle(QStringLiteral("My QQ")); //设置主窗体的标题toolBtn1_1 = new QToolButton;toolBtn1_1->setText(QStringLiteral("张三"));toolBtn1_1->setIcon(QPixmap("11.png"));toolBtn1_1->setIconSize(QPixmap("11.png").size());toolBtn1_1->setAutoRaise(true);toolBtn1_1->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);toolBtn1_2 = new QToolButton;toolBtn1_2->setText(QStringLiteral("李四"));toolBtn1_2->setIcon(QPixmap("12.png"));toolBtn1_2->setIconSize(QPixmap("12.png").size());toolBtn1_2->setAutoRaise(true);toolBtn1_2->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);toolBtn1_3 = new QToolButton;toolBtn1_3->setText(QStringLiteral("王五"));toolBtn1_3->setIcon(QPixmap("13.png"));toolBtn1_3->setIconSize(QPixmap("13.png").size());toolBtn1_3->setAutoRaise(true);toolBtn1_3->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);toolBtn1_4 = new QToolButton;toolBtn1_4->setText(QStringLiteral("小赵"));toolBtn1_4->setIcon(QPixmap("14.png"));toolBtn1_4->setIconSize(QPixmap("14.png").size());toolBtn1_4->setAutoRaise(true);toolBtn1_4->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);toolBtn1_5 = new QToolButton;toolBtn1_5->setText(QStringLiteral("小孙"));toolBtn1_5->setIcon(QPixmap("155.png"));toolBtn1_5->setIconSize(QPixmap("155.png").size());toolBtn1_5->setAutoRaise(true);toolBtn1_5->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);QGroupBox *groupBox1 = new QGroupBox;QVBoxLayout *layout1 = new QVBoxLayout(groupBox1);layout1->setMargin(10);                         //布局中各窗体的显示间距layout1->setAlignment(Qt::AlignHCenter);        //布局中各窗体的显示位置//加入抽屉内的各个按钮layout1->addWidget(toolBtn1_1);layout1->addWidget(toolBtn1_2);layout1->addWidget(toolBtn1_3);layout1->addWidget(toolBtn1_4);layout1->addWidget(toolBtn1_5);//插入一个占位符layout1->addStretch();toolBtn2_1 = new QToolButton;toolBtn2_1->setText(QStringLiteral("小王"));toolBtn2_1->setIcon(QPixmap("21.png"));toolBtn2_1->setIconSize(QPixmap("21.png").size());toolBtn2_1->setAutoRaise(true);toolBtn2_1->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);toolBtn2_2 = new QToolButton;toolBtn2_2->setText(QStringLiteral("小张"));toolBtn2_2->setIcon(QPixmap("22.png"));toolBtn2_2->setIconSize(QPixmap("22.png").size());toolBtn2_2->setAutoRaise(true);toolBtn2_2->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);QGroupBox *groupBox2 = new QGroupBox;QVBoxLayout *layout2 = new QVBoxLayout(groupBox2);layout2->setMargin(10);layout2->setAlignment(Qt::AlignHCenter);layout2->addWidget(toolBtn2_1);layout2->addWidget(toolBtn2_2);toolBtn3_1 = new QToolButton;toolBtn3_1->setText(QStringLiteral("小陈"));toolBtn3_1->setIcon(QPixmap("31.png"));toolBtn3_1->setIconSize(QPixmap("31.png").size());toolBtn3_1->setAutoRaise(true);toolBtn3_1->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);toolBtn3_2 = new QToolButton;toolBtn3_2->setText(QStringLiteral("小李"));toolBtn3_2->setIcon(QPixmap("32.png"));toolBtn3_2->setIconSize(QPixmap("32.png").size());toolBtn3_2->setAutoRaise(true);toolBtn3_2->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);QGroupBox *groupBox3 = new QGroupBox;QVBoxLayout *layout3 = new QVBoxLayout(groupBox3);layout3->setMargin(10);layout3->setAlignment(Qt::AlignHCenter);layout3->addWidget(toolBtn3_1);layout3->addWidget(toolBtn3_2);//将准备好的抽屉插入ToolBox中this->addItem((QWidget*)groupBox1,QStringLiteral("我的好友"));this->addItem((QWidget*)groupBox2,QStringLiteral("陌生人"));this->addItem((QWidget*)groupBox3,QStringLiteral("黑名单"));
}
  • toolBtn1_1 = new QToolButton:创建一个QToolButton类实例,分别对应于抽屉中的每个按钮。
  • toolBtn1_1->setText(QStringLiteral(“张三”)):设置按钮文字。
  • toolBtn1_1->setIcon(QPixmap(“11.png”)):设置按钮图标。
  • toolBtn1_1->setIconSize(QPixmap(“11.png”).size()):设置按钮的大小,本例将其设置与图标的大小相同。
  • toolBtn1_1->setAutoRaise(true):当鼠标离开时,按钮自动恢复为弹起状态。
  • toolBtn1_1->setToolButtonStyle(Qt::ToolButtonTextBesideIcon):设置按钮的ToolButtonStyle属性。ToolButtonStyle属性主要用于描述按钮的文字和图标的显示方式。Qt定义了五种ToolButtonStyle类型,可以根据需要选择显示的方式。
    • Qt::ToolButtonIconOnly:只显示图标。
    • Qt::ToolButtonTextOnly:只显示文字。
    • Qt::ToolButtonTextBesideIcon:文字显示在图标旁边。
    • Qt::ToolButtonTextUnderIcon:文字显示在图标下面。
    • Qt::ToolButtonFollowStyle:遵循Style标准。
  • QGroupBox *groupBox1 = new QGroupBox:创建一个QGroupBox类实例,在本例中对应每一个抽屉。
  • QVBoxLayout *layout1 = new QVBoxLayout(groupBox1):创建一个QVBoxLayout类实例,用来设置抽屉内各个按钮的布局。
  • layout1->addStretch():在按钮之后插入一个占位符,使得所有按钮能够靠上对齐,并且在整个抽屉大小发生变化时保证按钮的大小不发生变化。

进度条QProgressBar

Qt提供了两种显示进度条的方式:一种是嵌入到界面中的QProgressBar,这种进度条提供了一种横向或纵向显示进度的控件表达方式,用来描述任务的完成情况;另一种是QProgressDialog,提供了一种针对慢速过程的进度对话框表示方式,用于描述任务完成的进度情况。标准的进度条对话框包括一个进度显示条、一个“取消”按钮以及一个标签。
下面以一个Progress项目对控件功能进行说明,项目界面QProgressBar效果如下。
在这里插入图片描述
项目界面QProgressDialog效果如下。
在这里插入图片描述

界面效果布局代码如下:

ProgressDlg::ProgressDlg(QWidget *parent): QDialog(parent)
{QFont font("ZYSong18030",12);setFont(font);setWindowTitle(QStringLiteral("Progress"));FileNum =new QLabel;FileNum->setText(QStringLiteral("文件数目:"));FileNumLineEdit =new QLineEdit;FileNumLineEdit->setText(QStringLiteral("100000"));ProgressType =new QLabel;ProgressType->setText(QStringLiteral("显示类型:"));comboBox =new QComboBox;comboBox->addItem(QStringLiteral("progressBar"));comboBox->addItem(QStringLiteral("progressDialog"));progressBar =new QProgressBar;starBtn =new QPushButton();starBtn->setText(QStringLiteral("开始"));mainLayout =new QGridLayout(this);mainLayout->addWidget(FileNum,0,0);mainLayout->addWidget(FileNumLineEdit,0,1);mainLayout->addWidget(ProgressType,1,0);mainLayout->addWidget(comboBox,1,1);mainLayout->addWidget(progressBar,2,0,1,2);mainLayout->addWidget(starBtn,3,1);mainLayout->setMargin(15);mainLayout->setSpacing(10);connect(starBtn,SIGNAL(clicked()),this,SLOT(startProgress()));
}

功能代码如下:

void ProgressDlg::startProgress()
{bool ok;int num =FileNumLineEdit->text().toInt(&ok);if(comboBox->currentIndex()==0)     	//采用进度条的方式显示进度{progressBar->setRange(0,num);for(int i=1;i<num+1;i++){progressBar->setValue(i);}}else if(comboBox->currentIndex()==1)	//采用进度对话框显示进度{//创建一个进度对话框QProgressDialog *progressDialog=new QProgressDialog(this);QFont font("ZYSong18030",12);progressDialog->setFont(font);progressDialog->setWindowModality(Qt::WindowModal);progressDialog->setMinimumDuration(5);progressDialog->setWindowTitle(QStringLiteral("Please Wait"));progressDialog->setLabelText(QStringLiteral("Copying..."));progressDialog->setCancelButtonText(QStringLiteral("Cancel"));progressDialog->setRange(0,num);	  //设置进度对话框的步进范围for(int i=1;i<num+1;i++){progressDialog->setValue(i);if(progressDialog->wasCanceled())return;}}
}

以下是对一些关键代码的说明:

  • int num =FileNumLineEdit->text().toInt(&ok):获取当前需要复制的文件数目,这里对应进度条的总步进值。
  • progressBar->setRange(0,num):设置进度条范围从0到需要复制的文件数目。
  • progressBar->setValue(i):模拟每一个文件的复制过程,进度条总的步进值为需要复制的文件数目。当复制完一个文件后,步进值增加1。
  • progressDialog->setWindowModality(Qt::WindowModal):设置进度对话框采用模态方式进行显示,即在显示进度的同时,其他窗口不响应输入信号。
  • progressDialog->setMinimumDuration(5):设置进度对话框出现需要等待的时间,此处设置为5秒,默认4秒。
  • progressDialog->setWindowTitle(QStringLiteral(“Please Wait”)):设置进度对话框的窗体标题。
  • progressDialog->setLabelText(QStringLiteral(“Copying…”)):设置进度对话框的显示文字信息。
  • progressDialog->setCancelButtonText(QStringLiteral(“Cancel”)):设置进度对话框的“取消”按钮显示的文字。
  • progressDialog->setValue(i):模拟每个文件的复制过程,进度条总的步进值为需要复制的文件数目。当复制完一个文件后,步进增加1。
  • if(progressDialog->wasCanceled()):检测“取消”按钮是否被触发,若触发则退出循环并关闭进度对话框。

QProgressBar有以下几个需要关注的属性:

  • minimum、maximum:决定进度条指示的最小值和最大值。
  • format:决定进度条显示文字的格式,可以有三种显示格式,即%p%、%v和%m。其中,%p%显示完成百分比,这是默认显示方式;%v显示当前的进度之;%m显示总的步进值。
  • invertedAppearance:可以使进度条以反方向显示进度。

QProgressDialog类也有几个属性需要关注:

  • minimum、maximum:表示进度条的最小值和最大值,决定了进度条的变化范围。
  • minimumDuration:表示进度条对话框出现前的等待时间。系统根据所需完成时间的工作量估算一个预计花费的时间内,若大于设定的等待时间,则出现进度条对话框;若小于设定的等待时间,则不出现进度条对话框。

调色板与电子钟

在应用中需要改变某个控件的颜色外观,如背景、文字颜色等。Qt提供了调色板类QPalette专门用于管理对话框的外观显示。QPalette类相当于对话框或控件的调色板,它管理着控件或窗口的所有颜色信息。每个窗体或控件都包含一个QPalette对象,在显示时,按照它的QPalette对象中对各部分状态下的颜色的描述进行绘制。
此外,Qt还提供了QTime类用于获取和 显示系统时间。

QPalette类

这个小节详细介绍QPalette类的使用方法,该类有两个基本概念:一个是QPalette::ColorGroup,另一个是QPalette::ColorRole。其中,QPalette::ColorGroup指的是以下三种不同的状态。

  • QPalette::Active:获得焦点的状态。
  • QPalette::Inactive:未获得焦点的状态。
  • QPalette::Disabled:不可用状态。

其中,Active状态与Inactive状态在通常情况下,颜色显示是一致的,也可以根据需要设置为不一样的颜色。
QPalette::ColorRole指的是颜色主题,即对窗体中不同部位颜色的分类。例如,QPalette::Window是指背景色,QPalette::WindowText是指前景色,等等。
QPalette类使用频度最高的函数是setColor,其函数原型如下:

void QPalette::setColor(QPalette::ColorGroup group, QPalette::ColorRole role, const QColor &color)

在对主题颜色进行设置的同时,还区分了状态,即对某个主题在某个状态下的颜色进行了设置:

void QPalette::setColor(QPalette::ColorRole role, const QColor &color)

只对某个主题的颜色进行设置,并不区分状态。
QPalette类同时还提供setBrush函数,通过画刷的设置对显示进行更改,这样就可能使用图片而不仅是单一的颜色来对主题进行填充。Qt之前的版本中有关背景色设置的函数如使用图片而不仅是单一的颜色来对主题进行填充。Qt之前的版本中有关背景色设置的函数如setBackgroundColor或前景色设置的函数如setForegroundColor在Qt5中都被废止,统一由QPalette进行管理。例如,setBackgroundColor函数可由以下语句代替:

xxx->setAutoFillBackground(true);
QPalette p = xxx->palette();
// 如果不是使用单一的颜色填充背景,则也可以将setColor函数换为setBrush函数对背景主题进行设置。
p.setColor(QPalette::Window,color); // p.setBrush(QPalette::Window,brush);
//把修改后的调色板信息应用到contentFrame窗体中,更新显示
xxx->setPalette(p);

以上代码段要首先调用setAutoFillBackground(true)设置窗体自动填充背景。
创建一个Palette项目,利用QPalette改变控件颜色的方法。项目实现的窗体分为两部分:左半部分用于不同主题颜色的选择,右半部分用于显示选择的颜色对窗体外观的改变。运行效果如下图所示。
在这里插入图片描述
创建颜色选择区代码如下:

void Palette::createCtrlFrame()
{ctrlFrame =new QFrame;                  //颜色选择面板windowLabel =new QLabel(QStringLiteral("QPalette::Window: "));windowComboBox =new QComboBox;			//创建一个QComboBox对象fillColorList(windowComboBox);connect(windowComboBox,SIGNAL(activated(int)),this,SLOT(ShowWindow()));//(b)windowTextLabel =new QLabel(QStringLiteral("QPalette::WindowText: "));windowTextComboBox =new QComboBox;fillColorList(windowTextComboBox);connect(windowTextComboBox,SIGNAL(activated(int)),this,SLOT(ShowWindowText()));buttonLabel =new QLabel(QStringLiteral("QPalette::Button: "));buttonComboBox =new QComboBox;fillColorList(buttonComboBox);connect(buttonComboBox,SIGNAL(activated(int)),this,SLOT(ShowButton()));buttonTextLabel =new QLabel(QStringLiteral("QPalette::ButtonText: "));buttonTextComboBox =new QComboBox;fillColorList(buttonTextComboBox);connect(buttonTextComboBox,SIGNAL(activated(int)),this,SLOT(ShowButtonText()));baseLabel =new QLabel(QStringLiteral("QPalette::Base: "));baseComboBox =new QComboBox;fillColorList(baseComboBox);connect(baseComboBox,SIGNAL(activated(int)),this,SLOT(ShowBase()));QGridLayout *mainLayout=new QGridLayout(ctrlFrame);mainLayout->setSpacing(20);mainLayout->addWidget(windowLabel,0,0);mainLayout->addWidget(windowComboBox,0,1);mainLayout->addWidget(windowTextLabel,1,0);mainLayout->addWidget(windowTextComboBox,1,1);mainLayout->addWidget(buttonLabel,2,0);mainLayout->addWidget(buttonComboBox,2,1);mainLayout->addWidget(buttonTextLabel,3,0);mainLayout->addWidget(buttonTextComboBox,3,1);mainLayout->addWidget(baseLabel,4,0);mainLayout->addWidget(baseComboBox,4,1);
}
void Palette::fillColorList(QComboBox *comboBox)
{QStringList colorList = QColor::colorNames();QString color;foreach(color,colorList)						//对颜色名列表进行遍历{QPixmap pix(QSize(70,20));	pix.fill(QColor(color));                    //为pix填充当前遍历的颜色comboBox->addItem(QIcon(pix),NULL);comboBox->setIconSize(QSize(70,20));comboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);}
}
void Palette::ShowWindow()
{//获得当前选择的颜色值QStringList colorList = QColor::colorNames();QColor color = QColor(colorList[windowComboBox->currentIndex()]);QPalette p = contentFrame->palette();p.setColor(QPalette::Window,color);//把修改后的调色板信息应用到contentFrame窗体中,更新显示contentFrame->setPalette(p);contentFrame->update();
}
  • fillColorList(windowTextComboBox):向下拉列表框中插入各种不同的颜色选项。
  • connect(windowComboBox,SIGNAL(activated(int)),this,SLOT(ShowWindow())):连接下拉列表框的activity信号与改变背景色的槽函数ShowWindow。
  • QPalette p = contentFrame->palette():获得右部窗体contentFrame的调色板信息。
  • p.setColor(QPalette::Window,color):设置contentFrame窗体的Window类颜色,即背景色,setColor的第一个参数为设置的颜色主题,第二个参数为具体的颜色值。
  • QStringList colorList = QColor::colorNames():获得Qt所有内置名称的颜色列表,返回的是一个字符串列表colorList。
  • QColor color:新建一个QString对象,为循环遍历做准备。
  • QPixmap pix(QSize(70,20)):新建一个QPixmap对象pix作为显示颜色的图标。
  • comboBox->addItem(QIcon(pix),NULL):调用QComboBox的addItem函数为下拉列表框插入一个条目,并以准备好的pix作为插入条目的图标,名称设为NULL,即不显示颜色的名称。
  • comboBox->setIconSize(QSize(70,20)):设置图标的尺寸,图标默认尺寸是一个正方形,将它设置为与pix尺寸相同的长方形。
  • comboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents):设置下拉列表框的尺寸调整策略为AdjustToContents(符合内容的大小)。

QTime类

QTime的currentTime函数用于获取当前的系统时间;QTime的toString函数的参数需要指定转换后的显示格式。

  • H/h:小时(若使用H表示小时,则无论何时都以24小时制显示小时;若使用h表示小时,则当同时指定AM/PM时,采用12小时制显示小时,其他情况下仍采用24小时制进行显示。)
  • m:分。
  • s:秒
  • AP/A:显示AM或PM。
  • Ap/a:显示am或pm。

可根据实际显示需要进行格式设置,例如:
hh:mm:ss A 22:30:08 PM
H:mm:s a 10:30:8 pm

QTime的toString函数也可直接利用Qt::DateFormat作为参数指定时间显示的格式,如Qt::TextDate、Qt::ISODate、Qt::ISODateWithMs等。

创建一个Clock项目,通过实现显示于桌面上并可随意拖拽至桌面任意位置的电子时钟,实践QPalette类和mousePressEvent/mouseMoveEvent类的用法。页面ui效果如下图所示。
在这里插入图片描述
界面布局代码如下:

DigiClock::DigiClock(QWidget *parent):QLCDNumber(parent)
{/* 设置时钟背景 */QPalette p=palette();p.setColor(QPalette::Window,Qt::blue);setPalette(p);setWindowFlags(Qt::FramelessWindowHint);setWindowOpacity(0.5);QTimer *timer=new QTimer(this);			//新建一个定时器对象connect(timer,SIGNAL(timeout()),this,SLOT(showTime()));timer->start(1000);showTime();								//初始时间显示resize(150,60);							//设置电子时钟显示的尺寸showColon=true;                            //初始化
}
  • QPalette p=palette()、p.setColor(QPalette::Window,Qt::blue)、setPalette§:将电子时钟窗体背景色设置为蓝色。
  • setWindowFlags(Qt::FramelessWindowHint):设置窗体标识,此处设置为一个没有面板边框和标题栏的窗体。
  • setWindowOpacity(0.5):设置窗体的透明度为0.5,即半透明。
  • timer->start(1000):以1000毫秒为周期启动定时器。

显示电子钟的显示时间功能槽函数showTime具体代码如下:

void DigiClock::showTime()
{QTime time=QTime::currentTime();QString text=time.toString("hh:mm");if(showColon){text[2]=':';showColon=false;}else{text[2]=' ';showColon=true;}display(text);								//显示转换好的字符串时间
}
  • QTime time=QTime::currentTime():获取当前的系统时间,保存在一个QTime对象中。
  • QString text=time.toString(“hh:mm”):把获取的当前时间转换为字符串你类型。

通过执行鼠标按下的事件响应函数mousePressEvent(QMouseEvent *event)和鼠标移动事件响应函数mouseMoveEvent(QMouseEvent *event)的重定义,可以实现用鼠标在桌面上随意拖拽电子时钟。
在鼠标按下响应函数mousePressEvent(QMouseEvent *event)中,首先判断按下的按键是否为鼠标左键。若按下的键是鼠标左键,则保存当前鼠标点所在的位置相对于窗体左上角的偏移值dragPosition;若按下的键是鼠标右键,则退出窗体。
在鼠标移动响应函数mouseMoveEvent(QMouseEvent *event)中,首先判断当前鼠标状态,调用event->buttons()返回鼠标的状态,若为左侧按键,则调用QWidget的move函数将窗体移动至鼠标当前点。由于move函数的参数指定的是窗体的左上角位置,所以要使用鼠标当前点的位置减去相对窗体左上角的偏移值dragPosition。
具体功能函数代码如下:

void DigiClock::mousePressEvent(QMouseEvent *event)
{if(event->button()==Qt::LeftButton){dragPosition=event->globalPos()-frameGeometry().topLeft();event->accept();}if(event->button()==Qt::RightButton){close();}
}
void DigiClock::mouseMoveEvent(QMouseEvent *event)
{if(event->buttons()&Qt::LeftButton){move(event->globalPos()-dragPosition);event->accept();}
}

可扩展对话框

可扩展对话框通常用于用户对界面有不同要求的场合。通常情况下,只出现基本对话框窗体;当供高级用户使用或需要更多信息时,可通过某种方式的切换显示完整对话框窗体(扩展窗体),切换工作通常一个按钮来实现。
可扩展对话框的基本实现方法是利用setSizeConstraint(QLayout::SetFixedSize)方法使对话框尺寸保持相对固定。其中,最关键的部分有以下两点。

  • 在整个对话框的构造函数中调用。
layout->setSizeConstraint(QLayout::SetFixedSize)

这个设置保证了对话框的尺寸保持相对固定,始终保持各个控件组合的默认尺寸。在扩展部分显示时,对话框尺寸根据需要显示的控件被扩展;而在扩展部分隐藏时,对话框尺寸又恢复至初始状态。

  • 切换按钮的实现。整个窗体可扩展的工作都是在此按钮所连接的槽函数中完成的。

创建一个ExtensionDlg项目,设置一个简单地填写资料窗口。通常情况下,只需要填写姓名、性别。若有特殊需要,还需要填写更多信息,则切换至完整对话框窗体,运行效果如下图所示。
未展开的样式
展开时的样式
窗口构造函数如下:

ExtensionDlg::ExtensionDlg(QWidget *parent): QDialog(parent)
{setWindowTitle(QStringLiteral("Extension Dialog"));	 //设置对话框的标题栏信息createBaseInfo();createDetailInfo();QVBoxLayout *layout =new QVBoxLayout(this);             //布局layout->addWidget(baseWidget);layout->addWidget(detailWidget);layout->setSizeConstraint(QLayout::SetFixedSize);layout->setSpacing(10);
}
  • layout->setSizeConstraint(QLayout::SetFixedSize):设置窗体的大小固定,不能利用拖拽改变大小,否则当在此单击“详细”按钮时,对话框不能恢复到初始状态。

createBaseInfo函数完成基本窗口的布局,代码如下:

void ExtensionDlg::createBaseInfo()
{baseWidget =new QWidget;QLabel *nameLabel =new QLabel(QStringLiteral("姓名:"));QLineEdit *nameLineEdit =new QLineEdit;QLabel *sexLabel =new QLabel(QStringLiteral("性别:"));QComboBox *sexComboBox =new  QComboBox;sexComboBox->insertItem(0,QStringLiteral("女"));sexComboBox->insertItem(1,QStringLiteral("男"));QGridLayout *LeftLayout =new QGridLayout;LeftLayout->addWidget(nameLabel,0,0);LeftLayout->addWidget(nameLineEdit,0,1);LeftLayout->addWidget(sexLabel);LeftLayout->addWidget(sexComboBox);QPushButton *OKBtn =new QPushButton(QStringLiteral("确定"));QPushButton *DetailBtn =new QPushButton(QStringLiteral("详细"));QDialogButtonBox *btnBox =new QDialogButtonBox(Qt::Vertical);btnBox->addButton(OKBtn,QDialogButtonBox::ActionRole);btnBox->addButton(DetailBtn,QDialogButtonBox::ActionRole);QHBoxLayout *mainLayout =new QHBoxLayout(baseWidget);mainLayout->addLayout(LeftLayout);mainLayout->addWidget(btnBox);connect(DetailBtn, &QPushButton::clicked, this, &ExtensionDlg::showDetailInfo);//connect(DetailBtn, SIGNAL(clicked()), this, SLOT(showDetailInfo()));
}

createDetailInfo函数实现详细窗体部分窗口布局,代码如下:

void ExtensionDlg::createDetailInfo()
{detailWidget =new QWidget;QLabel *ageLabel =new QLabel(QStringLiteral("年龄:"));QLineEdit *ageLineEdit =new QLineEdit;ageLineEdit->setText(QStringLiteral("30"));QLabel *departmentLabel =new QLabel(QStringLiteral("部门:"));QComboBox *departmentComBox =new QComboBox;departmentComBox->addItem(QStringLiteral("部门1"));departmentComBox->addItem(QStringLiteral("部门2"));departmentComBox->addItem(QStringLiteral("部门3"));departmentComBox->addItem(QStringLiteral("部门4"));QLabel *emailLabel =new QLabel(QStringLiteral("email:"));QLineEdit *emailLineEdit =new QLineEdit;QGridLayout *mainLayout =new QGridLayout(detailWidget);mainLayout->addWidget(ageLabel,0,0);mainLayout->addWidget(ageLineEdit,0,1);mainLayout->addWidget(departmentLabel,1,0);mainLayout->addWidget(departmentComBox,1,1);mainLayout->addWidget(emailLabel,2,0);mainLayout->addWidget(emailLineEdit,2,1);detailWidget->hide();
}

单击“详细”按钮时,调用showDetailInfo函数,函数功能代码如下:

void ExtensionDlg::showDetailInfo()
{if(detailWidget->isHidden())detailWidget->show();else detailWidget->hide();
}

不规则窗体

常见的窗体通常是各种方形的对话框,但有时也需要使用非方形的窗体,如圆形、椭圆形,甚至是不规则形状的对话框。
利用setMask函数为窗体设置遮罩,实现不规则窗体,设置遮罩后的窗体尺寸仍是原窗体大小,只是被遮罩的地方不可见。
创建一个ShapeWidget项目,实现一个蝴蝶图形外延形状的不规则形状对话框,也可以在不规则窗体上放置按钮等控件,可以通过鼠标左键拖拽窗体,单击鼠标右键关闭窗体。界面显示效果如下图所示。
在这里插入图片描述
界面布局代码如下:

ShapeWidget::ShapeWidget(QWidget *parent): QWidget(parent)
{QPixmap pix;						//新建一个QPixmap对象pix.load("16.png",0,Qt::AvoidDither|Qt::ThresholdDither|Qt::ThresholdAlphaDither);resize(pix.size());setMask(QBitmap(pix.mask()));
}
  • pix.load(“16.png”,0,Qt::AvoidDither|Qt::ThresholdDither|Qt::ThresholdAlphaDither):调用QPixmap的load函数为QPixmap对象填入图象值。
    load函数的原型如下:
bool QPixmap::load(const QString &fileName, const char *format = nullptr, Qt::ImageConversionFlags flags = Qt::AutoColor)

其中,参数fileName为图片文件名;参数format表示读取图片文件采用的格式,此处为0表示采用默认的格式;参数flags表示读取图片的方式,由Qt::ImageConversionFlags定义,此处设置的标识为避免图片的抖动方式。

  • resize(pix.size()):重设主窗体的尺寸为所读取的图片的大小。
  • setMask(QBitmap(pix.mask())):为调用它的控件增加一个遮罩,遮住所选区域以外的部分使其看起来是透明的,它的参数可为一个QPixmap对象或一个QRegion对象,实例中使用的是PNG格式的图片,它的透明部分实际上是一个遮罩。

程序启动画面(QSplashScreen)

创建一个SplashSreen项目,通过Qt提供的QSplashScreen类实现一个在程序启动过程中显示启动画面的功能。
下面是启动时的界面效果图。
在这里插入图片描述
启动完成后的正常界面如下。
在这里插入图片描述
页面启动显示启动画面功能代码如下:

int main(int argc, char *argv[])
{QApplication a(argc, argv);QPixmap pixmap("qt.webp");QSplashScreen splash(pixmap);splash.show();	//显示此启动图片a.processEvents();MainWindow w;w.show();splash.finish(&w);return a.exec();
}
  • QPixmap pixmap(“qt.webp”):创建一个QPixmap对象,设置启动图片(这里设置为"qt.webp")。
  • QSplashScreen splash(pixmap):利用QPixmap对象创建一个QSplashScreen对象。
  • a.processEvents():使程序在显示启动画面的同时仍能响应鼠标等其他事件。
  • MainWindow w、w.show():正常创建主窗体对象,并调用show函数显示。
  • splash.finish(&w):表示在主窗体对象初始化完成后,结束启动画面。

工程代码

文章涉及的所有代码可点击工程源码下载。

相关文章:

QT基本对话框(基本对话框、工具盒类、进度条、调色板与电子钟、可扩展对话框、程序启动画面)

此篇文章通过实例介绍基本对话框的用法。首先介绍标准文件对话框&#xff08;QFileDialog&#xff09;、标准颜色对话框&#xff08;QColorDialog&#xff09;、标准字体对话框&#xff08;QFontDialog&#xff09;、标准输入对话框&#xff08;QInputDialog&#xff09;以及标…...

Docker 部署 MariaDB 数据库 与 Adminer 数据库管理工具

文章目录 MariaDBmariadb.cnf开启 binlog Adminerdocker-compose.ymlAdminer 连接 MariaDB MariaDB MariaDB是一个流行的开源关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;它是MySQL的一个分支和替代品。 官网&#xff1a;https://mariadb.com/镜像&#xff…...

qt 可以在一个函数中读一个文件,然后再将内容写入另一个文件中

是的&#xff0c;Qt 允许你在一个函数中读取一个文件的内容&#xff0c;并将这些内容写入到另一个文件中。这可以通过结合使用 QFile 和 QTextStream&#xff08;或 QDataStream&#xff0c;取决于你的具体需求&#xff09;来实现。以下是一个简单的示例&#xff0c;展示了如何…...

Dijkstra算法C代码

一个带权图n个点m条边&#xff0c;求起点到终点的最短距离 先定义一个邻接矩阵graph&#xff0c;graph[i][j]表示从i到j的距离&#xff0c;i到j没有路就表示为无穷 然后定义一个visit数组&#xff0c;visit[i]表示i结点是否被访问 然后定义一个dist数组&#xff0c;dist[i]表…...

P1064 [NOIP2006 提高组] 金明的预算方案

[NOIP2006 提高组] 金明的预算方案 题目描述 金明今天很开心&#xff0c;家里购置的新房就要领钥匙了&#xff0c;新房里有一间金明自己专用的很宽敞的房间。更让他高兴的是&#xff0c;妈妈昨天对他说&#xff1a;“你的房间需要购买哪些物品&#xff0c;怎么布置&#xff0…...

大型企业组网如何规划网络

大型企业组网是一个复杂的过程&#xff0c;它需要细致的规划和设计&#xff0c;以确保网络能够满足企业的业务需求&#xff0c;同时保证性能、安全性和可扩展性。以下是规划大型企业网络的一些关键步骤和考虑因素&#xff1a; 1. 需求分析 业务需求&#xff1a;与各个业务部门…...

java:aocache的单实例缓存(二)

之前一篇博客《java:aocache的单实例缓存》介绍了aoocache使用注解AoCacheable实现单实例缓存的方式&#xff0c;同时也指出了这种方式的使用限制&#xff0c;就是这个注解定义的构造方法&#xff0c;不能再创建出新实例。 为了更灵活方便的实现单实例。aocache最新版本0.4.0增…...

ElasticSearch安装部署

简介 Elasticsearch 是一个开源的分布式搜索和分析引擎&#xff0c;用于实时地存储、检索和分析大数据量。它基于 Apache Lucene 搜索引擎库构建而成&#xff0c;提供了一个强大、稳定且易于扩展的搜索解决方案。 主要特点和用途&#xff1a; 分布式存储和搜索&#xff1a; E…...

数据赋能(132)——开发:数据转换——影响因素、直接作用、主要特征

影响因素 数据转换过程中需要考虑的一些影响因素&#xff1a; 数据格式与结构&#xff1a; 不同系统或应用可能使用不同的数据格式&#xff08;如JSON、XML、CSV等&#xff09;和数据结构&#xff08;如关系型数据库、非关系型数据库等&#xff09;。数据转换需要确保原始数据…...

TMGM:ASIC撤销禁令,TMGM强化合规、重启差价合约服务

TMGM作为差价合约&#xff08;CFDs&#xff09;与保证金外汇交易领域的领航者&#xff0c;安全、合规、高效被奉为我集团的终身使命。澳大利亚证券和投资委员会&#xff08;ASIC&#xff09;已正式撤销了早前针对TMGM差价合约业务实施的临时止损令。这一误会的解除&#xff0c;…...

基于SpringBoot网吧管理系统设计和实现(源码+LW+调试文档+讲解等)

&#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者&#xff0c;博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌&#x1f497; Java精品实战案例《600套》 2025-2026年最值得选择的Java毕业设计选题大全&#xff1…...

实测2024年最佳的三款Socks5代理IP网站

一、引言 在浩瀚的网络世界中&#xff0c;Socks5代理IP服务如同导航灯塔&#xff0c;指引我们穿越数据海洋&#xff0c;安全、稳定地访问目标网站。作为专业的测评团队&#xff0c;我们深知一款优秀的Socks5代理IP网站需要具备哪些特质&#xff1a;稳定的IP资源、高效的连接速…...

Pythonnet能导入clr,但无法引入System模块?

【pythonnet详解】—— Python 和 .NET 互操作的库_pythonnet 详细使用-CSDN博客 Python中动态调用C#的dll动态链接库中方法_python 如何调用c# dll-CSDN博客 需求&#xff1a;Python调用并传List<float>类型参数给.Net 起初&#xff1a;直接 # 创建一个Python浮点数…...

媒体宣发套餐的概述及推广方法-华媒舍

在今天的数字化时代&#xff0c;对于产品和服务的宣传已经变得不可或缺。媒体宣发套餐作为一种高效的宣传方式&#xff0c;在帮助企业塑造品牌形象、扩大影响力方面扮演着重要角色。本文将揭秘媒体宣发套餐&#xff0c;为您呈现一条通往成功的路。 1. 媒体宣发套餐的概述 媒体…...

Windows和Linux C++判断磁盘空间是否充足

基本是由百度Ai写代码生成的&#xff0c;记录一下。实现此功能需要调用系统的API函数。 对于Windows&#xff0c;可调用函数GetDiskFreeSpaceEx&#xff0c;使用该函数需要包含头文件windows.h。该函数的原型&#xff1a; 它的四个参数&#xff1a; lpDirectoryName&#xff0…...

数据访问层如何提取数据到其他层,其他类中

当然可以&#xff0c;以下是一些具体的例子&#xff0c;展示了如何将数据库访问逻辑封装在一个单独的类中&#xff0c;并在其他类中使用这个类来获取数据。 数据库访问类&#xff08;DatabaseAccess.java&#xff09;&#xff1a; java复制代码 import java.sql.*; import ja…...

【JS】AI总结:JavaScript中常用的判空方法

在JavaScript中&#xff0c;判空是一个常见的操作&#xff0c;因为变量可能未定义、未初始化或包含特定的空值。以下是JavaScript中常用的判空方法&#xff1a; 使用if语句直接判断&#xff1a; 如果变量是null、undefined、0、NaN、空字符串&#xff08;""&#xff…...

Rust单元测试、集成测试

单元测试、集成测试 在了解了如何在 Rust 中写测试用例后&#xff0c;本章节我们将学习如何实现单元测试、集成测试&#xff0c;其实它们用到的技术还是上一章节中的测试技术&#xff0c;只不过对如何组织测试代码提出了新的要求。 单元测试 单元测试目标是测试某一个代码单…...

vue全局方法plugins/utils

一、在src目录下创建一个plugins文件夹 test.ts文件存放创建的方法&#xff0c;index.ts用于接收所有自定义方法进行统一处理 二、编写自定义方法 // test.ts文件 export default {handleTest(val1: number, val2: number) {// 只是一个求和的方法return val1 val2;}, };三…...

高阶算法班从入门到精通之路

课程介绍 本课程旨在帮助学员深入理解算法与数据结构的核心概念&#xff0c;从而掌握高级算法设计与分析技能。每集课程内容精心设计&#xff0c;涵盖了常用数据结构、经典算法及其应用场景等方面的深度讲解&#xff0c;同时通过大量实例演练&#xff0c;帮助学员提升解决实际…...

C++ 左值右值

文章目录 概述左值右值右值引用左值和右值的互换 小结 概述 左值和右值属于2中不同的表达式类型&#xff1b;它们在表达式中扮演不同的角色&#xff0c;特别是在赋值操作和函数参数传递中。 左值 定义&#xff1a;左值是指那些在内存中有确定位置的表达式&#xff0c;可以出…...

[数据集][目标检测]水面垃圾水面漂浮物检测数据集VOC+YOLO格式3749张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;3749 标注数量(xml文件个数)&#xff1a;3749 标注数量(txt文件个数)&#xff1a;3749 标注…...

[深度学习] 卷积神经网络CNN

卷积神经网络&#xff08;Convolutional Neural Network, CNN&#xff09;是一种专门用于处理数据具有类似网格结构的神经网络&#xff0c;最常用于图像数据处理。 一、CNN的详细过程&#xff1a; 1. 输入层 输入层接收原始数据&#xff0c;例如一张图像&#xff0c;它可以被…...

区别QPushButton和QToolButton

在刚开始学习Qt时,可能很难理解QPushButton和QToolButton之间的区别。 QToolButton通常用于QToolBar中,常常只显示图标,而不显示文本。那么,它们的主要区别是什么?什么时候应该使用QPushButton,什么时候应该使用QToolButton? 了解这一点很重要,这样我们才能选择最合适…...

【Python】已解决:TypeError: Object of type JpegImageFile is not JSON serializable

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;TypeError: Object of type JpegImageFile is not JSON serializable 一、分析问题背景 在进行Python编程时&#xff0c;特别是处理图像数据和JSON序列化时&…...

超简单的nodejs使用log4js保存日志到本地(可直接复制使用)

引入依赖 npm install log4js 新建配置文件logUtil.js const log4js require(log4js);// 日志配置 log4js.configure({appenders: {// 控制台输出consoleAppender: { type: console },// 文件输出fileAppender: {type: dateFile,filename: ./logs/default, //日志文件的存…...

Python面试宝典第1题:两数之和

题目 给定一个整数数组 nums 和一个目标值 target&#xff0c;找出数组中和为目标值的两个数的索引。可以假设每个输入只对应唯一的答案&#xff0c;且同样的元素不能被重复利用。比如&#xff1a;给定 nums [2, 7, 11, 15] 和 target 9&#xff0c;返回 [0, 1]&#xff0c;因…...

fastapi集成jwt

fastapi集成jwt fastapipython-jose实现jwt登录 1、安装相关包 python-jose pip install python-jose2、创建token及token校验 from copy import deepcopy from datetime import timedelta, datetimefrom jose import jwt, ExpiredSignatureErrorSECRET_KEY "xxx&quo…...

自定义一个背景图片的高度,随着容器高度的变化而变化,小于图片的高度时裁剪,大于时拉伸100%展示

1、通过js创建<image?>标签来获取背景图片的宽高比&#xff1b; 2、当元素的高度大于原有比例计算出来的高度时&#xff0c;背景图片的高度拉伸自适应100%&#xff0c;否则高度为auto&#xff0c;会自动被裁减 3、背景图片容器高度变化时&#xff0c;自动计算背景图片的…...

iPhone怎么恢复删除的数据?几款顶级iPhone数据恢复软件

从iOS设备恢复数据。 对于任何数据恢复软件来说&#xff0c;从iOS设备恢复数据都是一项复杂的任务&#xff0c;因为Apple已将众多数据保护技术集成到现代iPhone和iPad中。其中包括硬件加密和文件级加密。iOS 上已删除的数据只能通过取证文件工件搜索来找到&#xff0c;例如分析…...

macOS 上或linux安装 Jenkins

在 macOS 上使用 Docker 安装 Jenkins 的步骤如下&#xff1a; 安装 Docker: 如果尚未安装 Docker&#xff0c;请先从 Docker 官网下载并安装 Docker Desktop for Mac。 打开终端: 打开 macOS 上的终端应用程序。 拉取 Jenkins 镜像: 使用以下命令从 Docker Hub 拉取 Jenkins…...

axios发送数据的几种方式

axios 发送数据的几种方式 1、最简单的方式是将参数直接拼接在 URL 上&#xff0c;这通常用于传递少量的数据&#xff0c;例如资源的 ID。 const id 12; axios.delete(https://api.example.com/${id}).then(response > {console.log(Resource deleted successfully:, res…...

示例:WPF中推荐一个Diagram开源流程图控件

一、目的&#xff1a;分享一个自研的开源流程图控件 二、使用方法 1、引用Nuget包&#xff1a; 2、添加节点列表和绘图控件 <DockPanel><ItemsControl DockPanel.Dock"Left"><h:GeometryNodeData Text"节点"/></ItemsControl><…...

离线安装kubesphere-详细操作,以及报错

离线安装kubesphere 官网地址 https://kubesphere.io/zh/docs/v3.4/installing-on-linux/introduction/air-gapped-installation/ 1.先准备docker环境 [rootnode1 ~]# tar -xf docker-24.0.6.tgz [rootnode1 ~]# ls anaconda-ks.cfg calico-v3.26.1.tar docker …...

Python Coala库:代码质量检查与自动化修复的利器

更多Python学习内容&#xff1a;ipengtao.com 在软件开发过程中&#xff0c;代码质量至关重要。高质量的代码不仅易于维护和扩展&#xff0c;还能减少错误和提升效率。为了确保代码质量&#xff0c;我们常常需要依赖代码分析工具。Python的Coala库就是这样一个强大的工具&#…...

MyBatis(12)MyBatis 映射文件中的 resultMap

MyBatis 的 resultMap 是一种高级映射策略&#xff0c;用于处理复杂的SQL查询结果和Java对象之间的映射关系。resultMap 提供了比 auto-mapping 更为灵活的映射方式&#xff0c;它允许开发者显式指定数据库列和Java对象属性之间的映射关系&#xff0c;甚至可以处理复杂的数据结…...

C语言从入门到进阶(15万字总结)

前言&#xff1a; 《C语言从入门到进阶》这本书可是作者呕心沥血之作&#xff0c;建议零售价1元&#xff0c;当然这里开个玩笑。 本篇博客可是作者之前写的所有C语言笔记博客的集结&#xff0c;本篇博客不止有知识点&#xff0c;还有一部分代码练习。 有人可能会问&#xff…...

Java---Maven详解

一段新的启程&#xff0c; 披荆斩棘而前&#xff0c; 心中的梦想&#xff0c; 照亮每个黑暗的瞬间。 无论风雨多大&#xff0c; 我们都将坚强&#xff0c; 因为希望的火焰&#xff0c; 在胸中永不熄灭。 成功不是终点&#xff0c; 而是每一步的脚印&#xff0c; 用汗水浇灌&…...

服务器日志事件ID4107:从自动更新 cab 中提取第三方的根目录列表失败,错误为: 已处理证书链,但是在不受信任提供程序信任的根证书中终止。

在查看Windows系统日志时&#xff0c;你是否有遇到过事件ID4107错误&#xff0c;来源CAPI2&#xff0c;详细信息在 http://www.download.windowsupdate.com/msdownload/update/v3/static/trustedr/en/authrootstl.cab 从自动更新 cab 中提取第三方的根目录列表失败&#xff0c;…...

【高级篇】MySQL集群与分布式:构建弹性和高效的数据服务(十四)

引言 在探讨了《分区与分片》策略后,我们已经学会了如何在单一数据库层面有效管理大量数据和提升查询效率。本章,我们将踏上更高层次的探索之旅,深入MySQL集群与分布式技术的广阔领域。这些技术不仅能够横向扩展系统的处理能力和存储容量,还能显著增强数据服务的可靠性和响…...

vue3 学习记录

文章目录 props组合式组件 使用<script setup \>组合式组件 没有使用 <script setup\>选项式组件 this emits组合式组件 使用<script setup \>组合式组件 没有使用 <script setup\>选项式组件 this v-model 组件数据绑定单个model多个model实现 model …...

spring boot jar 启动报错 Zip64 archives are not supported

spring boot jar 启动报错 Zip64 archives are not supported 原因、解决方案问题为什么 spring boot 不支持 zip64zip、zip64 功能上的区别zip 的文件格式spring-boot-loader 是如何判断是否是 zip64 的&#xff1f; 参考 spring boot 版本是 2.1.8.RELEASE&#xff0c;引入以…...

BASH and SH in SHELL scripts

一、执行脚本的现象 为了测试一个小的功能&#xff0c;写了一个小脚本&#xff0c;类似的内容如下&#xff1a; #!/bin/shecho "start api test ......"for((i1;i<10;i)); do echo "cur id :" $i; done echo "end."执行一下&#xff0c;“…...

Qt Creator创建一个用户登录界面

目录 1 界面设计 2 代码 2.1 登录界面 2.2 注册界面 2.3 登陆后的界面 3 完整资源 这里主要记录了如何使用Qt Creator创建一个用户登录界面&#xff0c;能够实现用户的注册和登录功能&#xff0c;注册的用户信息存储在了一个文件之中&#xff0c;在登录时可以比对登录信息…...

等保测评练习卷14

等级保护初级测评师试题14 姓名&#xff1a; 成绩&#xff1a; 判断题&#xff08;10110分&#xff09; 1. 方案编制活动中测评对象确定、测评指…...

学懂C#编程:常用高级技术——学会C#多线程开发(三):学会线程池的使用

在C#中&#xff0c;线程池&#xff08;ThreadPool&#xff09;是一种用于管理线程的机制&#xff0c;它可以有效地重用线程&#xff0c;减少线程创建和销毁的开销&#xff0c;从而提高程序的性能。线程池通常用于执行不需要立即完成的任务&#xff0c;如后台任务、异步操作等。…...

maven-gpg-plugin插件

开源项目SDK&#xff1a;https://github.com/mingyang66/spring-parent 个人文档&#xff1a;https://mingyang66.github.io/raccoon-docs/#/ 一、敏感信息泄漏警告 执行mvn install或mvn deploy时控制台会报如下告警&#xff1a; [WARNING] Parameter passphrase (user pr…...

Linux——echo命令,管道符,vi/vim 文本编辑器

1.echo 命令 作用 向终端设备上输出字符串或变量的存储数据 格式 echo " 字符串 " echo $ 变 量名 [rootserver ~] # echo $SHELL # 输出变量的值必须加 $ /bin/bash [rootserver ~] # str1" 我爱中国 " # 自定义变量 echo 重定向输出到文件 ec…...

CISCN--西南半决赛--pwn

1.vuln 这是主函数&#xff0c;数一下就发现可以溢出最后的0x4008d0 然后会执行到这里&#xff0c;逻辑就是在v0上写shellcode&#xff0c;不过执行写0x10&#xff0c;不够sh&#xff0c;很明显要先read。 以下是exp: from pwn import * context.archamd64 ioprocess(./vuln)…...

DIYGW UniApp低代码可视化平台:高效、灵活、安全的应用开发新途径

一、引言 在数字化快速发展的今天&#xff0c;企业对于快速构建多端应用的需求日益增长。然而&#xff0c;传统的应用开发方式往往面临周期长、成本高、技术门槛高等问题。为了解决这些问题&#xff0c;DIYGW UniApp低代码可视化平台应运而生&#xff0c;它以高效率、多端使用…...

LeetCode 1667, 36, 199

目录 1667. 修复表中的名字题目链接表要求知识点思路代码 36. 有效的数独题目链接标签思路代码 199. 二叉树的右视图题目链接标签思路代码 1667. 修复表中的名字 题目链接 1667. 修复表中的名字 表 表Users的字段为user_id和name。 要求 编写解决方案&#xff0c;修复名字…...

Java中MD5加密算法的原理与实现详解

Java中MD5加密算法的原理与实现详解 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; MD5&#xff08;Message Digest Algorithm 5&#xff09;是一种广泛使用的…...

uniapp微信小程序使用xr加载模型

1.在根目录与pages同级创建如下目录结构和文件&#xff1a; // index.js Component({properties: {modelPath: { // vue页面传过来的模型type: String,value: }},data: {},methods: {} }) { // index.json"component": true,"renderer": "xr-frame&q…...

Linux系统中交叉编译opencv库

目标&#xff1a;将opencv进行交叉编译&#xff0c;使其能在rk3326板子上运行使用。 环境&#xff1a; ubuntu&#xff1a;18.04 opencv:4.5.4 opencv源码从挂网下载&#xff1a;opencv源码下载地址 交叉编译链&#xff1a;gcc-arm-10.3-linux-gun 一.环境准备 1.交叉编译链我…...

数据可视化如何为智慧农业带来变革

数据可视化如何为智慧农业保驾护航&#xff1f;随着农业现代化的深入推进&#xff0c;智慧农业应运而生&#xff0c;通过集成物联网、大数据、人工智能等先进技术&#xff0c;实现农业生产的数字化、智能化和高效化。而在这一过程中&#xff0c;数据可视化技术作为重要的工具&a…...

python 笔试面试八股(自用版~)

1 解释型和编译型语言的区别 解释是翻译一句执行一句&#xff0c;更灵活&#xff0c;eg&#xff1a;python; 解释成机器能理解的指令&#xff0c;而不是二进制码 编译是整个源程序编译成机器可以直接执行的二进制可运行的程序&#xff0c;再运行这个程序 比如c 2 简述下 Pyth…...

vmware中Ubuntu虚拟机和本地电脑Win10互相ping通

初始状态 使用vmware17版本安装的Ubuntu的20版本&#xff0c;安装之后什么配置都要不懂&#xff0c;然后进行下述配置。 初始的时候是NAT&#xff0c;没动的. 设置 点击右键编辑“属性” 常规选择“启用”&#xff1a; 高级选择全部&#xff1a; 打开网络配置&#xff0c;右键属…...

ROS基础学习-话题通信机制研究

研究ROS通信机制 研究ROS通信机制 0.前言1.话题通信1.1 理论模型1.2 话题通讯的基本操作1.2.1 C++1.2.2 Python中使用自己的虚拟环境包1.2.2.1 参考11.2.2.2 参考21.2.2.3 /usr/bin/env:“python”:没有那个文件或目录1.2.3 Python1.2.2.1 发布方1.2.2.2 订阅方1.2.2.3 添加可执…...

前端Vue小兔鲜儿电商项目实战Day01

一、项目介绍 1. 项目技术栈 2. 项目规模 3. 项目亮点 4. 课程安排 5. 适合人群 二、Vue3组合式API体验 1. 通过一个Counter案例体验Vue3新引入的组合式API ①Vue2的代码 <template><button click"addCount"> {{ count }}</button> </templ…...

arcgisPro将一个图层的要素复制到另一个图层

1、打开两个图层&#xff0c;如下&#xff0c;其中一个图层中有两个要素&#xff0c;需要将其中一个要素复制到另一个图层中&#xff0c;展示如下&#xff1a; 2、选中待复制要素&#xff0c;点击复制按钮&#xff0c;如下&#xff1a; 3、下拉粘贴按钮列表&#xff0c;选择【选…...

唯众云课堂:领航智慧教育,赋能职教未来,打造高效人才培养新平台

随着《中国智慧教育发展报告 2023》的发布&#xff0c;智慧教育被正式定义为数字教育发展的高级阶段。然而&#xff0c;各职院在智慧教育的发展道路上&#xff0c;往往面临着诸多挑战&#xff0c;如缺乏一体化教学平台、优质教学资源不足等。唯众凭借深厚的产业洞察与教育实践经…...

linux centos磁盘清理相关

清理磁盘流程 1、查看磁盘挂载路径及使用率 df -h2、查看当前文件下文件大小 du -sh *3、制空文件内容 > 文件名 ###制空当前文件内容&#xff0c;直接清0 列子 >access.loglinux操作系统中&#xff0c;经常会遇到磁盘空间满的问题。遇到这样的问题&#xff0c;先查下…...