题目要求:窗口与子部件的区别
(1)新建一个空的Qt项目:Project_1;
(2)在main函数中新建三个部件:一个widget,两个label。其中,一个label为子部件,即它的父对象为那个widget。分别设置它们的标题及文本。
(3)显示窗口:widget以及那个非子部件的label
#include
int main(int argc, char *argv[])
{
//应用程序类
//处理应用程序初始化和结束,事件处理调度。
QApplication a(argc, argv);
//新建QWidget类对象,默认parent参数nullptr,所以它是个窗口
QWidget*widget=new QWidget();
//设置窗口标题
widget->setWindowTitle(QObject::tr("我是widget"));
//新建QLabel对象,默认parent参数是nullptr,所以它是个窗口
QLabel *label=new QLabel();
label->setWindowTitle(QObject::tr("我是label"));
label->setText(QObject::tr("label:我是个窗口"));
label->resize(180,20);
//label2指定父窗口为widget,所以不是窗口
QLabel * label2=new QLabel(widget);
label2->setText(QObject::tr("label2:不是独立窗口,只是widget的子部件"));
label2->resize(250,20);
label->show();
widget->show();
int ret=a.exec();
delete label;
delete widget;
return ret;
}
题目要求:熟悉模态和非模态对话框
(1)新建一个Qt Widget Application项目:Project_2
(2)在主窗口类的构造函数中,设置主窗口的标题为:I’m the main window
(3)在主窗口类的构造函数中,定义一个基本对话框对象,设置其标题为:I’m a dialog
(4)在主窗口类的构造函数中,以模态形式显示(3)中定义的对话框
(5)撤消(4)操作,在主窗口类的构造函数中,以非模态形式显示(3)中定义的对话框
(6)分析比较模态和非模态对话框的行为
main.cpp
#include "widget.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//主窗口
Widget w;
w.setWindowTitle("I'm the main Window");
w.show();
return a.exec();
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include "QDialog"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//非模态对话框
QDialog dialog(this);
dialog.setWindowTitle("I'm a dialog");
dialog.resize(800,800);
dialog.exec();
// //模式对话框
// QDialog *dialog=new QDialog(this);
// dialog->setModal(true);
// dialog->setWindowTitle("I'm a dialog");
// dialog->resize(900,900);
// dialog->show();
}
Widget::~Widget()
{
delete ui;
}
题目要求:一个Qt界面程序的一般框架结构。通常,为程序的主窗口定义一个类,并在这个类中完成主窗口中的子部件的创建以及信号的处理。这样,程序的GUI部分全部放在主窗口中实现,便于管理和维护
(1)新建一个空的Qt项目:Project_3
(2)新建一个主窗口类,继承于Widget
(3)在main函数中定义一个主窗口实例,并显示。
(4)运行程序
(5)在主窗口中添加一个PushButton。注意:在主窗口类的构造函数中完成该操作,不要在main函数中。运行程序。
(6)通过Qt Designer在主窗口放置一个label标签,位置与(5)中的PushButton不要重叠,并设置其文本为:I’m a label。运行程序。
(7)尝试在主窗口类的构造函数中修改(6)中label的文本为:access from code。运行程序。
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include "QPushButton"
#include "QLabel"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QPushButton * Button=new QPushButton(this);
QLabel*label=new QLabel("I'm a label",this);
label->move(50,50);
label->setText("access from code");
}
Widget::~Widget()
{
delete ui;
}
一般
connect(button,&QPushButton::clicked,this,&Widget::changeLabelText);
传参
connect(button,&QPushButton::clicked,[=](){changeLabelText(label);});
这句话是一个信号槽连接的语句,用于将一个按钮的点击事件(clicked)与一个槽函数(changeLabelText)连接起来,并在点击按钮时执行该槽函数。具体来说:
1.button 是一个 QPushButton 类型的对象指针,表示一个按钮对象。
2.&QPushButton::clicked 是一个信号,表示按钮被点击时发出的信号。
3.[=]() 是一个 lambda 表达式,用于指定信号响应时要执行的槽函数。[=] 表示将当前作用域中的所有变量以值传递方式传入 lambda 表达式中,() 表示该 lambda 表达式不接受任何参数。
4.changeLabelText 是一个槽函数,表示要执行的函数名。这个函数应该在当前类或者其父类中实现。
5.label 是一个 QLabel 类型的对象指针,表示一个标签对象。
因此,这句话的意思是:当按钮被点击时,执行 changeLabelText 函数,并将其中的 label 指针传递给该函数。在 changeLabelText 函数中可以通过 label 指针来操作标签对象。
题目要求:熟悉信号槽机制。该题目在上面的Project_3上继续完成。
(1)在主窗口类中定义一个slot槽函数changeLabelText()。
(2)在主窗口类中把主窗口中PushButton的clicked信号与槽changeLabelText ()关联在一起.
(3)在showDlg()完成如下处理:如果主窗口中的label的文本为: access from code,则修改其文本为:I’m a label;反之,则修改为:access from code。提示:字符串比较,可以用QString中的compare函数。
#include "widget.h"
#include "ui_widget.h"
#include "QPushButton"
#include "QLabel"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QPushButton * button=new QPushButton("Change Label",this);
QLabel * label=new QLabel("I'm a label",this);
label->move(50,50);
label->setFixedSize(200,200);
connect(button,&QPushButton::clicked,[=](){changeLabelText(label);});
}
Widget::~Widget()
{
delete ui;
}
void Widget::changeLabelText(QLabel *label)
{
if(label->text().compare("access from code")==0)
{
label->setText("I'm a label");
}
else
{
label->setText("access from code");
}
}
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
public slots:
void changeLabelText(QLabel *label);
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
题目要求:熟悉标准对话框
(1)新建一个空的Qt项目:Project_4
(2)新建一个主窗口类,继承于Widget
(3)在Qt Designer中编辑主窗口界面,放置如教材中图3-11所示的按钮
(4)增加并关联每个按钮单击的信号槽
(5)在每个按钮对应的槽函数中,显示对应的标准对话框。
#include "widget.h"
#include "ui_widget.h"
#include "QDebug"
#include "QColorDialog"
#include "QFileDialog"
#include "QFontDialog"
#include "QLineEdit"
#include "QInputDialog"
#include "QMessageBox"
#include "QProgressDialog"
#include "QErrorMessage"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
errordlg=new QErrorMessage(this);
}
Widget::~Widget()
{
delete ui;
}
//颜色对话框
void Widget::on_pushButton_clicked()
{
QColor color=QColorDialog::getColor(Qt::red,this,tr("颜色对话框"));
qDebug()<<"color:"<pushButton_3->setFont(font);
}
else
{
qDebug()<setWindowTitle(tr("错误信息对话框"));
errordlg->showMessage(tr("这里是出错信息!"));
}
//3个向导页面
QWizardPage *Widget::createPage1()
{
QWizardPage *page=new QWizardPage;
page->setTitle(tr("介绍"));
return page;
}
QWizardPage *Widget::createPage2()
{
QWizardPage *page=new QWizardPage;
page->setTitle(tr("用户信息选择"));
return page;
}
QWizardPage *Widget::createPage3()
{
QWizardPage *page=new QWizardPage;
page->setTitle(tr("结束"));
return page;
}
//向导对话框
void Widget::on_pushButton_8_clicked()
{
QWizard wizard(this);
wizard.setWindowTitle(tr("向导对话框"));
wizard.addPage(createPage1());//添加向导页面
wizard.addPage(createPage2());
wizard.addPage(createPage3());
wizard.exec();
}
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
#include
QT_BEGIN_NAMESPACE
namespace Ui { class Widget;class QErrorMessage; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
void on_pushButton_4_clicked();
void on_pushButton_5_clicked();
void on_pushButton_6_clicked();
void on_pushButton_7_clicked();
void on_pushButton_8_clicked();
private:
Ui::Widget *ui;
QErrorMessage *errordlg;//错误消息对话框
//向导对话框
QWizardPage *createPage1();
QWizardPage *createPage2();
QWizardPage *createPage3();
};
#endif // WIDGET_H
Lab6
1.布局设计
二、使用Designer进行布局设计
(1) 建立一个以QWidget为窗口的项目Project_1
(2) 在Designer中,设计教材图4-2(旧版4-3)所示的界面
(3) 定义如图中所示的热键(提示:要设定Buddy关系);确定每个部件的Tab order
(4) 性别下拉框中,加入“男”,“女”两项
(5) 年龄范围设为(10-60),步长为1
(6) PushButton的文本改为“保存”
(7) 为“保存”按钮定义一个单击槽函数,处理如下事情:1. 检查姓名、邮箱项是否为空,如果是空的,弹出一个对话框,提示哪项不能为空;2. 如果检查通过了,则根据姓名、性别、年龄和邮箱生成一个数据,保存到一个链表list中。同时,利用qDebug函数输出该数据,看看是否正确。提示: 可以定义一个结构体DataItem, 再使用std::list定义一个链表. std::list为C++标准库中的链表实现, 为一个模板类, 使用时需要#include
#include "widget.h"
#include "ui_widget.h"
#include "QShortcut"
#include "QMessageBox"
#include "QDebug"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//连接保存按钮
connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(on_saveButton_clicked()));
//设置性别下拉框内容
ui->sexComboBox->addItem("男");
ui->sexComboBox->addItem("女");
//设置年龄滑动条范围和步长
ui->ageSlider->setRange(10,60);
ui->ageSlider->setSingleStep(1);
//创建快捷键
QShortcut *nameShortcut=new QShortcut(QKeySequence("Ctrl+N"),this);
connect(nameShortcut,SIGNAL(activated()),ui->nameEdit,SLOT(setFocus()));
QShortcut* sexShortcut = new QShortcut(QKeySequence("Ctrl+S"), this);
connect(sexShortcut, SIGNAL(activated()), ui->sexComboBox, SLOT(setFocus()));
QShortcut* ageShortcut = new QShortcut(QKeySequence("Ctrl+A"), this);
connect(ageShortcut, SIGNAL(activated()), ui->ageSlider, SLOT(setFocus()));
QShortcut* emailShortcut = new QShortcut(QKeySequence("Ctrl+E"), this);
connect(emailShortcut, SIGNAL(activated()), ui->emailEdit, SLOT(setFocus()));
//部件跳转
//以便用户可以方便地从一个组件跳转到另一个组件,并且键盘输入的焦点将正确地移动到下一个组件。
ui->label_name->setBuddy(ui->nameEdit);
ui->label_sex->setBuddy(ui->sexComboBox);
ui->label_age->setBuddy(ui->ageSlider);
ui->label_email->setBuddy(ui->emailEdit);
//tab切换顺序
//确保在按下Tab键时,焦点将正确地移动到下一个组件。
QWidget::setTabOrder(ui->nameEdit, ui->sexComboBox);
QWidget::setTabOrder(ui->sexComboBox, ui->ageSlider);
QWidget::setTabOrder(ui->ageSlider, ui->emailEdit);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_saveButton_clicked()
{
//获取输入数据
QString name=ui->nameEdit->text();
QString sex=ui->sexComboBox->currentText();
int age =ui->ageSlider->value();
QString email=ui->emailEdit->text();
//检查数据是否为空
if(name.isEmpty())
{
QMessageBox::warning(this,"提示","姓名不能为空");
return;
}
if(email.isEmpty())
{
QMessageBox::warning(this,"提示","邮箱不能为空");
return;
}
//保存数据到链表
DataItem item={name,sex,age,email};
dataList.push_back(item);
//输出
qDebug()<<"姓名:"<
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
struct DataItem{
QString name;
QString sex;
int age;
QString emainl;
};
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_saveButton_clicked();
private:
Ui::Widget *ui;
std::list dataList;
};
#endif // WIDGET_H
2.数据界面互动
三、数据与界面互动:扩展Project_1的功能
(1) 把窗口最下面的LineEdit替换为两个按钮:Pre, Next.
(2) 按下Pre键,窗口显示list中的上一条记录,按下Next键显示list中的下一条记录。
#include "widget.h"
#include "ui_widget.h"
#include "QMessageBox"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
ui->spinBox_age->setRange(10,60);
ui->spinBox_age->setSingleStep(1);
connect(ui->pushButton_Pre,SIGNAL(clicked()),this,SLOT(on_Prebutton_Clicked()));
connect(ui->pushButton_next,SIGNAL(clicked()),this,SLOT(on_Nextbutton_Clicked()));
connect(ui->pushButton_save,SIGNAL(clicked()),this,SLOT(on_Savebutton_Clicked()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_Savebutton_Clicked()
{
QString name=ui->lineEdit_name->text();
int age=ui->spinBox_age->value();
if(name.isEmpty())
{
QMessageBox::warning(this,"提示","姓名不能为空");
return;
}
DataItem item={name,age};
dataList.push_back(item);
currentData++;
allData++;
}
void Widget::updateData()
{
ui->lineEdit_name->setText(dataList[currentData].name);
ui->spinBox_age->setValue(dataList[currentData].age);
}
void Widget::on_Prebutton_Clicked()
{
if(currentData>0)
{
currentData--;
updateData();
}
}
void Widget::on_Nextbutton_Clicked()
{
if(currentData
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
struct DataItem{
QString name;
int age;
};
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;
int allData=-1;
int currentData=-1;
QList dataList;
void updateData();
private slots:
void on_Prebutton_Clicked();
void on_Nextbutton_Clicked();
void on_Savebutton_Clicked();
};
#endif // WIDGET_H
3.多窗口切换
四、做一基于QWidget的程序,上面有一个QTextEdit,还有两个按钮“登录”“更改密码”,请注意以上三个部件要求使用合理布局。当点击登录时,跳出登录界面如图所示用户能输入用户名、密码.
当用户输入用户名和密码后,点击登录,登录窗口关闭,如果用户名密码正确,程序提示,登陆成功,并在主窗口QTextEdit钟显示“{用户名}登陆成功!”如果用户输入用户密码错误时,在窗口的中心部件提示提示用户输入错误,请重新输入。
#include "widget.h"
#include "ui_widget.h"
#include "QDialog"
#include "QLabel"
#include "QLineEdit"
#include "QPushButton"
#include "QHBoxLayout"
#include "QVBoxLayout"
#include "QMessageBox"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
//点击登录按钮
connect(ui->pushButton_log,SIGNAL(clicked()),this,SLOT(on_Login_Button_Clicked()));
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_Login_Button_Clicked()
{
//创建新界面
QDialog loginDialog(this);
loginDialog.setWindowTitle("Login");
//新建界面
QLabel *usernameLabel=new QLabel("Username:");
QLineEdit *usernameLineEdit=new QLineEdit;
QLabel *passwordLabel=new QLabel("Password:");
QLineEdit *passwordLineEdit=new QLineEdit;
//setEchoMode 是 Qt 框架中 QLineEdit 类的一个函数,用于设置文本框中输入的内容是否回显。
//它有以下几种模式:
//QLineEdit.Normal:默认模式,输入的字符将会回显。
//QLineEdit.NoEcho:输入的字符将不会回显,常用于密码等敏感信息的输入。
//QLineEdit.Password:输入的字符将会被掩盖,以密文形式显示。
//QLineEdit.PasswordEchoOnEdit:输入的字符在编辑时将会被掩盖,但在输入完成后会以密文形式显示。
passwordLineEdit->setEchoMode(QLineEdit::Password);
QPushButton *loginButton=new QPushButton("Login");
QPushButton *cancelButton=new QPushButton("Cancel");
//QHBoxLayout 是 Qt 框架中的一个布局类,用于水平排列子部件。
//它将子部件按照左到右的方向依次排列,并且会自动调整子部件的大小和位置以适应布局
QHBoxLayout *buttonLayout=new QHBoxLayout;//创建水平布局
buttonLayout->addWidget(loginButton);//加入水平布局
buttonLayout->addWidget(cancelButton);
//QVBoxLayout 是 Qt 框架中的一个布局类,用于垂直排列子部件。
//它将子部件按照上到下的方向依次排列,并且会自动调整子部件的大小和位置以适应布局。
QVBoxLayout *mainLayout=new QVBoxLayout;//创建垂直布局
mainLayout->addWidget(usernameLabel);//加入垂直布局
mainLayout->addWidget(usernameLineEdit);
mainLayout->addWidget(passwordLabel);
mainLayout->addWidget(passwordLineEdit);
mainLayout->addLayout(buttonLayout);//水平和垂直布局结合
//布局加入主界面
loginDialog.setLayout(mainLayout);
//实现登录按钮功能
connect(loginButton,&QPushButton::clicked,[&](){
QString username=usernameLineEdit->text();
QString password=passwordLineEdit->text();
if(username=="zyy"&&password=="666")
{
loginDialog.accept();
}
else
{
QMessageBox::warning(&loginDialog,"Error","Invalid username or password. Please try again.");
}
});
loginDialog.setModal(true);//设置模态窗口
loginDialog.exec();
}
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_Login_Button_Clicked();
private:
Ui::Widget *ui;
QTextEdit *textEdit;
};
#endif // WIDGET_H
Lab7
1.PushButton按钮组件
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
// 设置函数,用于绑定事件
void Print()
{
std::cout << "hello lyshark" << std::endl;
}
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 创建[退出]按钮
QPushButton * btn = new QPushButton; // 创建一个按钮
// btn->show(); // 用顶层方法弹出按钮
btn->setParent(this); // 设置父窗体(将btn内嵌到主窗体中)
btn->setText("退出"); // 设置按钮text显示
btn->move(100,200); // 移动按钮位置
btn->resize(100,50); // 设置按钮大小
btn->setEnabled(true); // 设置是否可被点击
// 创建[触发信号]按钮
QPushButton * btn2 = new QPushButton("触发信号",this);
btn2->setParent(this);
btn2->move(100,100);
btn2->resize(100,50);
// 设置主窗体常用属性
this->resize(500,400); // 重置窗口大小,调整主窗口大小
this->setWindowTitle("我的窗体"); // 重置主窗体的名字
this->setFixedSize(1024,300); // 固定窗体大小(不让其修改)
// this->showFullScreen(); // 设置窗体全屏显示
// 设置主窗体特殊属性
// setWindowFlags(Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint); // 隐藏标题栏
// 为按钮绑定事件 connect(信号的发送者,发送的信号,信号的接受者,处理的函数(槽函数))
connect(btn,&QPushButton::clicked,this,&QWidget::close);
// 将窗体中的 [触发信号] 按钮,连接到Print函数中.
connect(btn2,&QPushButton::clicked,this,&Print);
}
MainWindow::~MainWindow()
{
delete ui;
}
2.LineEdit单行输入组件
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 设置计算和编辑框不可修改
ui->NumberSum->setEnabled(false);
ui->lineEdit_hex->setEnabled(false);
ui->lineEdit_bin->setEnabled(false);
// 设置为密码输入
ui->NumberSum->setEchoMode(QLineEdit::Password);
}
MainWindow::~MainWindow()
{
delete ui;
}
// 当点击计算按钮后完成计算
void MainWindow::on_pushButton_clicked()
{
// 得到两个编辑框的数据
QString string_total;
QString Number_One = ui->numberA->text();
QString Number_Two = ui->NumberB->text();
if(Number_One.length() == 0 || Number_Two.length() == 0)
{
ui->label_3->setText("参数不能为空");
}
else
{
// 类型转换并赋值
int number_int = Number_One.toInt();
float number_float = Number_Two.toFloat();
// 计算结果并放入到第三个编辑框中
float total = number_int * number_float;
string_total = string_total.sprintf("%.2f",total);
ui->NumberSum->setText(string_total);
}
}
// 当点击进制转换按钮后触发事件
void MainWindow::on_pushButton_2_clicked()
{
QString str = ui->lineEdit->text();
int value = str.toUInt();
// 转十六进制
str = str.setNum(value,16); // 转为16进制
str = str.toUpper(); // 变为大写
ui->lineEdit_hex->setText(str); // 设置hex编辑框
// 转二进制
str = str.setNum(value,2); // 第一种方式转换
str = QString::number(value,2); // 第二种方式转换
ui->lineEdit_bin->setText(str); // 设置bin编辑框
}
3.简易登录界面
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
#include
QString m_user="admin"; // 初始化用户名
QString m_pswd="12345"; // 初始化密码
int m_tryCount=0; // 试错次数
// 字符串MD5算法加密
QString MainWindow::encrypt(const QString &str)
{
QByteArray btArray;
btArray.append(str); // 加入原始字符串
QCryptographicHash hash(QCryptographicHash::Md5); // Md5加密算法
hash.addData(btArray); // 添加数据到加密哈希值
QByteArray resultArray =hash.result(); // 返回最终的哈希值
QString md5 =resultArray.toHex(); // 转换为16进制字符串
return md5;
}
// 读取用户名密码
void MainWindow::ReadString()
{
QString organization="UserDataBase"; // 注册表
QString appName="onley"; // HKEY_CURRENT_USER/Software/UserDataBase/onley
QSettings settings(organization,appName); // 创建key-value
bool saved=settings.value("saved",false).toBool(); // 读取 saved键的值
m_user=settings.value("Username", "admin").toString(); // 读取 Username 键的值,缺省为admin
QString defaultPSWD=encrypt("12345"); // 缺省密码 12345 加密后的数据
m_pswd=settings.value("PSWD",defaultPSWD).toString(); // 读取PSWD键的值
if (saved)
{
ui->lineEdit_Username->setText(m_user);
}
ui->checkBox->setChecked(saved);
}
// 保存用户名密码设置
void MainWindow::WriteString()
{
QSettings settings("UserDataBase","onley"); // 注册表键组
settings.setValue("Username",m_user); // 用户名
settings.setValue("PSWD",m_pswd); // 经过加密的密码
settings.setValue("saved",ui->checkBox->isChecked());
}
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
ui->setupUi(this);
setFixedSize(this->width(), this->height()); // 窗口不可调节
ui->lineEdit_Password->setEchoMode(QLineEdit::Password); // 密码输入
ReadString();
}
MainWindow::~MainWindow()
{
delete ui;
}
// login
void MainWindow::on_pushButton_clicked()
{
QString user=ui->lineEdit_Username->text().trimmed();//输入用户名
QString pswd=ui->lineEdit_Password->text().trimmed(); //输入密码
QString encrptPSWD=encrypt(pswd); //对输入密码进行加密
if ((user==m_user)&&(encrptPSWD==m_pswd)) //如果用户名和密码正确
{
WriteString();
QMessageBox::critical(this,"成功","已登录");
}
else
{
m_tryCount++; //错误次数
if (m_tryCount>3)
{
QMessageBox::critical(this, "错误", "输入错误次数太多,强行退出");
this->close();
}
else
{
QMessageBox::warning(this, "错误提示", "用户名或密码错误");
}
}
}
4.SpinBox组件
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->doubleSpinBox->setEnabled(false);
}
MainWindow::~MainWindow()
{
delete ui;
}
// 实现精度计算功能
void MainWindow::on_pushButton_3_clicked()
{
int x = ui->spinBox->value();
int y = ui->spinBox_2->value();
double total = x+y;
ui->doubleSpinBox->setValue(total); // 设置SpinBox数值(设置时无需转换)
QString label_value = ui->label_10->text(); // 获取字符串
ui->label_10->setNum(total); // 设置label标签为数字
}
- 自动触发运算
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->doubleSpinBox->setEnabled(false);
// 将数量和单价两个SpinBox的valueChanged()信号与on_pushButton_clicked()槽关联
// 只要spinBox中的内容发生变化,则立即触发按钮完成计算
QObject::connect(ui->spinBox,SIGNAL(valueChanged(int)),this,SLOT(on_pushButton_clicked()));
QObject::connect(ui->spinBox_2,SIGNAL(valueChanged(int)),this,SLOT(on_pushButton_clicked()));
QObject::connect(ui->doubleSpinBox,SIGNAL(valueChanged(double)),this,SLOT(on_pushButton_clicked()));
}
// By : LyShark
// https://www.cnblogs.com/lyshark
MainWindow::~MainWindow()
{
delete ui;
}
// 实现精度计算功能
void MainWindow::on_pushButton_clicked()
{
int x = ui->spinBox->value();
int y = ui->spinBox_2->value();
double total = x+y;
ui->doubleSpinBox->setValue(total); // 设置SpinBox数值(设置时无需转换)
QString label_value = ui->label_10->text(); // 获取字符串
ui->label_10->setNum(total); // 设置label标签为数字
}
5.HorizontalSlider 滑块条组件
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 将 SliderGreen,SliderBlue,SliderAlpha 与第一个滑块条 SliderRead 关联起来
// 实现效果为,当其他三个选择条数值改变时,同样会触发on_SliderRed_valueChanged槽函数
QObject::connect(ui->SliderRed,SIGNAL(valueChanged(int)),this,SLOT(on_SliderRed_valueChanged(int)));
QObject::connect(ui->SliderGreen,SIGNAL(valueChanged(int)),this,SLOT(on_SliderRed_valueChanged(int)));
QObject::connect(ui->SliderBlue,SIGNAL(valueChanged(int)),this,SLOT(on_SliderRed_valueChanged(int)));
QObject::connect(ui->SliderAlpha,SIGNAL(valueChanged(int)),this,SLOT(on_SliderRed_valueChanged(int)));
}
MainWindow::~MainWindow()
{
delete ui;
}
// 当拖动SliderRed滑块条时设置TextEdit底色
void MainWindow::on_SliderRed_valueChanged(int value)
{
Q_UNUSED(value);
QColor color;
int R=ui->SliderRed->value(); // 读取SliderRed的当前值
int G=ui->SliderGreen->value(); // 读取 SliderGreen 的当前值
int B=ui->SliderBlue->value(); // 读取 SliderBlue 的当前值
int alpha=ui->SliderAlpha->value();// 读取 SliderAlpha 的当前值
color.setRgb(R,G,B,alpha); // 使用QColor的setRgb()函数获得颜色
QPalette pal=ui->textEdit->palette(); // 获取textEdit原有的 palette
pal.setColor(QPalette::Base,color); // 设置palette的基色(即背景色)
ui->textEdit->setPalette(pal); // 设置为textEdit的palette,改变textEdit的底色
}
6.数码表与LCD屏幕
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
#include
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
// By : LyShark
// https://www.cnblogs.com/lyshark
MainWindow::~MainWindow()
{
delete ui;
}
// 当圆形选择框数值改变时设置数码表显示
void MainWindow::on_dial_valueChanged(int value)
{
ui->LCDDisplay->display(value);
}
// 选中时设置为十进制显示
void MainWindow::on_radioBtnDec_clicked()
{
ui->LCDDisplay->setDigitCount(3); // 设置位数
ui->LCDDisplay->setDecMode(); // 十进制
}
// 选中设置为二进制显示
void MainWindow::on_radioBtnBin_clicked()
{
ui->LCDDisplay->setDigitCount(8);
ui->LCDDisplay->setBinMode();
}
// 选中设置为八进制显示
void MainWindow::on_radioBtnOct_clicked()
{
ui->LCDDisplay->setDigitCount(5);
ui->LCDDisplay->setOctMode();
}
// 选中设置为十六进制显示
void MainWindow::on_radioBtnHex_clicked()
{
ui->LCDDisplay->setDigitCount(3);
ui->LCDDisplay->setHexMode();
}
7.CheckBox 多选框
多选框CheckBox
组件也是最常用的组件,多选框支持三态选择,选中半选中和未选中状态。
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->checkBox->setTristate(); // 启用三态选择框
ui->checkBox->setEnabled(true); // 设置为可选状态
}
MainWindow::~MainWindow()
{
delete ui;
}
// 三态选择框状态
void MainWindow::on_checkBox_stateChanged(int state)
{
// 选中状态
if (state == Qt::Checked)
{
ui->checkBox->setText("选中");
}
// 半选状态
else if(state == Qt::PartiallyChecked)
{
ui->checkBox->setText("半选");
}
// 未选中
else
{
ui->checkBox->setText("未选中");
}
}
// 设置取消选中
void MainWindow::on_pushButton_clicked()
{
int check = ui->checkBox->isCheckable();
if(check == 1)
{
ui->checkBox->setChecked(false);
}
}
// 关联式多选框
void MainWindow::on_checkBox_master_stateChanged(int state)
{
// 选中所有子框
if(state == Qt::Checked)
{
ui->checkBox_sub_a->setChecked(true);
ui->checkBox_sub_b->setChecked(true);
}
// 取消子框全选状态
if(state == Qt::Unchecked)
{
ui->checkBox_sub_a->setChecked(false);
ui->checkBox_sub_b->setChecked(false);
}
}
8.ComBox 下拉框组件
该组件提供了下拉列表供用户选择,ComBox组件除了可以显示下拉列表外,每个项还可以关联一个QVariant类型的变量用于存储不可见数据。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
// 定义为全局变量
QMap City_Zone;
QMap> map;
QList tmp;
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 循环方式添加元素
ui->comboBox_main->clear();
QIcon icon;
icon.addFile(":/image/1.ico");
for(int x=0;x<10;x++)
{
ui->comboBox_main->addItem(icon,QString::asprintf("元素_%d",x));
}
// 批量添加combox元素
ui->comboBox_main->clear();
QStringList str;
str << "北京" << "上海" << "广州";
ui->comboBox_main->addItems(str);
ui->comboBox_main->setItemIcon(0,QIcon(":/image/1.ico"));
ui->comboBox_main->setItemIcon(1,QIcon(":/image/2.ico"));
ui->comboBox_main->setItemIcon(2,QIcon(":/image/3.ico"));
// 实现combox联动效果
ui->comboBox_main->clear();
City_Zone.insert("请选择",0);
City_Zone.insert("北京",1);
City_Zone.insert("上海",2);
City_Zone.insert("广州",3);
// 循环填充一级菜单
ui->comboBox_main->clear();
foreach(const QString &str,City_Zone.keys())
{
ui->comboBox_main->addItem(QIcon(":/image/1.ico"),str,City_Zone.value(str));
}
// 插入二级菜单
tmp.clear();
tmp << "大兴区" << "昌平区" << "东城区";
map["北京"] = tmp;
tmp.clear();
tmp << "黄浦区" << "徐汇区" << "长宁区" << "杨浦区";
map["上海"] = tmp;
tmp.clear();
tmp << "荔湾区" << "越秀区";
map["广州"] = tmp;
// 设置默认选择第三个
ui->comboBox_main->setCurrentIndex(3);
}
MainWindow::~MainWindow()
{
delete ui;
}
// 获取当前选中的两级菜单内容
void MainWindow::on_pushButton_clicked()
{
QString one = ui->comboBox_main->currentText();
QString two = ui->comboBox_submain->currentText();
std::cout << one.toStdString().data() << " | " << two.toStdString().data() << std::endl;
}
// 当主ComBox被选择时,自动的填充第2个ComBox中的数据.
void MainWindow::on_comboBox_main_currentTextChanged(const QString &arg1)
{
ui->comboBox_submain->clear();
QList qtmp;
qtmp = map.value(arg1);
for(int x=0;xcomboBox_submain->addItem(QIcon(":/image/2.ico"),qtmp[x]);
}
}
9.ProgressBar 进度条与定时器
进度条ProgressBar
组件通常会结合QTimer
定时器组件共同使用,首先我们需要设置一个时钟周期,定时器每经过一定的时间周期则执行对变量或进度条的递增操作,由此实现进度条动态输出效果。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
QTimer *my_timer;
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 初始化进度条数值
ui->progressBar->setValue(0);
ui->progressBar_2->setValue(100);
// 声明定时器
my_timer = new QTimer(this);
// 绑定一个匿名函数
connect(my_timer,&QTimer::timeout,[=]{
static int x = 0;
// 判断是否到达了进度条的最大值
if(x != 100)
{
x++;
ui->progressBar->setValue(x);
ui->progressBar_2->setValue(int(100-x));
}
else
{
x=0;
my_timer->stop();
}
});
}
MainWindow::~MainWindow()
{
delete ui;
}
// 启动定时器,并设置周期为100毫秒
void MainWindow::on_pushButton_clicked()
{
if(my_timer->isActive() == false)
{
my_timer->start(100);
}
}
// 停止定时器
void MainWindow::on_pushButton_2_clicked()
{
if(my_timer->isActive() == true)
{
my_timer->stop();
}
}
// 将进度条置空
void MainWindow::on_pushButton_3_clicked()
{
ui->progressBar->setValue(0);
ui->progressBar_2->setValue(100);
}
10.DateTime 日期与时间组件
时间组件中包括了可以显示时间的QTime
显示日期的QDate
以及可同时显示时间与日期的QDateTime
这三种组件,三种组件的使用上几乎一致,如下代码是开发中最常用的总结。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
// 获取当前日期时间,并初始化到组件中
void MainWindow::on_pushButton_clicked()
{
QDateTime curDateTime = QDateTime::currentDateTime();
ui->timeEdit->setTime(curDateTime.time());
ui->dateEdit->setDate(curDateTime.date());
ui->dateTimeEdit->setDateTime(curDateTime);
ui->lineEdit->setText(curDateTime.toString("yyyy-MM-dd hh:mm:ss"));
}
// 将字符串时间日期转换到时间日期组件中
void MainWindow::on_pushButton_2_clicked()
{
QString str = ui->lineEdit_2->text();
str = str.trimmed();
if(!str.isEmpty())
{
QDateTime datetime = QDateTime::fromString(str,"yyyy-MM-dd hh:mm:ss");
ui->dateTimeEdit_string_to_datetime->setDateTime(datetime);
}
}
11.PlainTextEdit 多行文本框
多行文本编辑器,用于显示和编辑多行简单文本,如下代码左侧PlainTextEdit
中输入数据(每行换行)点击按钮后自动将左侧数据放入右侧的listView
组件中。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
#include
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 状态栏的创建
QStatusBar * stBar = statusBar();
setStatusBar(stBar);
QLabel * label = new QLabel("左侧提示信息",this);
stBar->addWidget(label);
QLabel * label2 = new QLabel("右侧提示信息",this);
stBar->addPermanentWidget(label2);
}
MainWindow::~MainWindow()
{
delete ui;
}
// 点击按钮实现将 plainTextEdit 里面的数据逐行放入到右侧
void MainWindow::on_pushButton_clicked()
{
QTextDocument* doc = ui->plainTextEdit->document (); // 文本对象
int count = doc->blockCount(); // 定义回车为分隔符
// 定义data,model用于存储每个文本
QStringList data;
QStringListModel *model;
for(int x=0;x< count;x++)
{
QTextBlock textLine = doc->findBlockByNumber(x); // 每次取出plainTextEdit中的一行
QString str = textLine.text();
data << str; // 放入链表中
}
// 显示到ListView中
model = new QStringListModel(data);
ui->listView->setModel(model);
}
12.RadioButton 单选框分组
单选框是最常用的组件,在一个界面中可以有多种单选框,每种单选框都会对应一个问题,此实我们需要使用ButtonGroup
组件对单选框进行分组,并通过信号和槽函数相互绑定,从而实现对用户的多种选择进行判断。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
QButtonGroup *group_sex;
QButtonGroup *group_hobby;
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 将不同的RadioButton放入不同的ButtonGroup组中
group_sex = new QButtonGroup(this);
group_sex->addButton(ui->radioButton_male,0);
group_sex->addButton(ui->radioButton_female,1);
group_sex->addButton(ui->radioButton_unknown,2);
ui->radioButton_unknown->setChecked(true);
group_hobby = new QButtonGroup(this);
group_hobby->addButton(ui->radioButton_eat,3);
group_hobby->addButton(ui->radioButton_drink,4);
group_hobby->addButton(ui->radioButton_sleep,5);
ui->radioButton_eat->setChecked(true);
// 绑定信号和槽
connect(ui->radioButton_male,SIGNAL(clicked(bool)),this,SLOT(MySlots()));
connect(ui->radioButton_female,SIGNAL(clicked(bool)),this,SLOT(MySlots()));
connect(ui->radioButton_unknown,SIGNAL(clicked(bool)),this,SLOT(MySlots()));
}
MainWindow::~MainWindow()
{
delete ui;
}
// 手动创建一个槽函数,此处的槽函数声明需要加入到头文件private slots中
void MainWindow::MySlots()
{
switch(group_sex->checkedId())
{
case 0:
std::cout << "male" << std::endl;
break;
case 1:
std::cout << "female" << std::endl;
break;
case 2:
std::cout << "unknown" << std::endl;
break;
}
}
Lab8
1.处理文档菜单
用Qt做一个基于主窗口的程序,用于处理文档,要求如下:
1.要有菜单,其中至少有3个常用菜单项具有图标,快捷键,图标是基于qt资源的;
2.要有工具栏,工具栏中有主要菜单项的按钮;
3.状态栏,用于显示软件名称、作者,文档信息(字数或当前行列数,自定)
4.有“关于”菜单项,弹出关于对话框,显示软件作者姓名、软件名称、开发日期
5.软件“登录”菜单项,用于验证用户名、密码,点击登录菜单项后,弹出登录对话框,当用户输入用户名、密码点击确定,核对已有用户名和密码,核对通过则进入,否则提示错误,并且重试;当登陆成功后,登陆菜单项变为灰色;“退出当前用户”变为可用
6.当登陆成功后,状态栏显示临时信息“当前用户为***(你登陆的用户名)”
7.能够打开硬盘上已有记事本文档(使用标准对话框中的文件打开对话框)
8.能够保存窗口显示文字为txt文件
9.能够使用字体选择组合框更改显示字体
10.右键弹出式菜单,能够关闭程序和选择字体。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_currentFile = "Project_2.txt";
m_softwareName = "My Text Editor";
m_author = "zyy";
m_softwareName = "My Text Editor";
m_developmentDate = "2023/05/28";
createActions();//菜单
createToolBars();//工具栏
//createToolButtons();
createStatusBar();//状态栏
showContextMenu();//右键菜单
}
MainWindow::~MainWindow()
{
delete ui;
}
//菜单初始状态
void MainWindow::createActions()
{
//打开菜单项
connect(ui->actionOpen_O,&QAction::triggered,this,&MainWindow::openFile);
//保存菜单项
connect(ui->actionSave_S,&QAction::triggered,this,&MainWindow::saveFile);
//退出菜单项
connect(ui->actionExit,&QAction::triggered,this,&MainWindow::close);
//登录菜单项
connect(ui->actionLogin_M,&QAction::triggered,this,&MainWindow::login);
//退出登录菜单项
connect(ui->actionLogout_N,&QAction::triggered,this,&MainWindow::logout);
ui->actionLogout_N->setEnabled(false);//设为不可用
//关于菜单项
connect(ui->actionAbout_A,&QAction::triggered,this,&MainWindow::about);
//字体选择组合框
// 将QTextEdit的字体设置为QFontComboBox当前选择的字体
connect(ui->fontComboBox, &QFontComboBox::currentFontChanged, this, &MainWindow::onFontChanged);
}
void MainWindow::openFile()
{
//getOpenFileName打开一个对话框,让用户选择一个文件并返回它的文件名
//QString QFileDialog::getOpenFileName(
//QWidget *parent = nullptr, //对话框的父窗口
//const QString &caption = QString(), //对话框的标题
//const QString &dir = QString(), //对话框打开的初始目录
//const QString &filter = QString(), //文件过滤器
//QString *selectedFilter = nullptr, //用户选择的过滤器
//Options options = Options()) //对话框的选项
//该函数返回用户选择的文件名,如果用户取消选择则返回空字符串。
QString fileName=QFileDialog::getOpenFileName(
this,tr("Open File"),"",
tr("Text Files(*.txt);;All Files(*)"));
if (!fileName.isEmpty())
{
//根据路径读取文件
QFile file(fileName);
//以只读文本模式打开文件
//QIODevice::ReadOnly表示以只读方式打开文件,
//QIODevice::Text表示以文本模式打开文件
if(file.open(QIODevice::ReadOnly|QIODevice::Text))
{
//创建一个QTextStream对象并将其与一个文件关联
//则可用>><<进行读写操作
QTextStream in(&file);
ui->textEdit->setPlainText(in.readAll());//清空原有文本,写入新文本
file.close();
m_currentFile=fileName;
setWindowTitle(m_currentFile + " - " + m_softwareName);
}
else
{
QMessageBox::warning(this,
tr("Open File"),
tr("Cannot open file: %1").arg(fileName)
);
}
}
}
void MainWindow::saveFile()
{
if (m_currentFile == "Project_2.txt")
{
QString fileName = QFileDialog::getSaveFileName(
this, tr("Save File"), "",
tr("Text Files (*.txt);;All Files (*)")
);
if (!fileName.isEmpty())
{
m_currentFile = fileName;
setWindowTitle(m_currentFile + " - " + m_softwareName);
}
else
{
return;
}
}
QFile file(m_currentFile);
if (file.open(QIODevice::WriteOnly | QIODevice::Text))
{
QTextStream out(&file);
out << ui->textEdit->toPlainText();//写入文件
file.close();
QMessageBox::information(this, tr("Save File"), tr("File saved successfully."));
}
else
{
QMessageBox::warning(this,
tr("Save File"),
tr("Cannot save file: %1").arg(m_currentFile));
}
}
void MainWindow::login()
{
bool ok;
QString username = QInputDialog::getText(this, tr("Login"), tr("Username:"),
QLineEdit::Normal, "", &ok);
if (ok && !username.isEmpty())
{
QString password = QInputDialog::getText(this, tr("Login"), tr("Password:"),
QLineEdit::Password, "", &ok);
if (ok && !password.isEmpty())
{
if (username == "zyy" && password == "666")
{
m_username = username;
ui->actionLogin_M->setEnabled(false);
ui->actionLogout_N->setEnabled(true);
QMessageBox::information(this, tr("Login"), tr("Login successfully."));
updateStatus();//更新状态栏
}
else
{
QMessageBox::warning(
this, tr("Login"),
tr("Incorrect username or password.")
);
login();
}
}
}
}
void MainWindow::logout()
{
m_username = "";
ui->actionLogin_M->setEnabled(true);
ui->actionLogout_N->setEnabled(false);
}
void MainWindow::about()
{
QMessageBox::about(
this, tr("About"),
tr("%1\nVersion 1.0\n\nAuthor: %2\nDevelopment Date: %3")
.arg(m_softwareName).arg(m_author).arg(m_developmentDate)
);
}
//void MainWindow::createToolButtons()
//{
// ui->toolBtn->setText(tr("File"));
// ui->toolBtn->setFixedSize(100, 50);
// ui->toolBtn->addAction(ui->actionOpen_O);
// ui->toolBtn->addAction(ui->actionSave_S);
// ui->toolBtn->addAction(ui->actionExit);
// //设置弹出模式
// ui->toolBtn->setPopupMode(QToolButton::MenuButtonPopup);
//}
void MainWindow::createToolBars()
{
m_toolbar = addToolBar(tr("File"));
m_toolbar->addAction(ui->actionOpen_O);
m_toolbar->addAction(ui->actionSave_S);
m_toolbar->addSeparator();
m_toolbar->addAction(ui->actionExit);
}
void MainWindow::createStatusBar()
{
ui->statusBar->showMessage(tr("Welcome ~"),20000);//停留时间20000
//创建标签
QLabel *permanent=new QLabel(this);
//设置一个 QFrame 的边框样式为 Box 和 Sunken
permanent->setFrameStyle(QFrame::Box|QFrame::Sunken);
permanent->setText("wwwwwwww");
ui->statusBar->addPermanentWidget(permanent);//加入状态栏
}
void MainWindow::updateStatus()
{
QLabel *statusText=new QLabel(this);
if (!m_username.isEmpty())
{
statusText->setText( tr("Current user is %1").arg(m_username));
}
ui->statusBar->clearMessage();//清空状态栏
ui->statusBar->addPermanentWidget(statusText);//加入状态栏
}
void MainWindow::onFontChanged(const QFont &font)
{
ui->textEdit->setFont(font);//设置新字体
}
void MainWindow::onChooseFont()
{
bool ok;
//用于打开一个字体选择对话框,让用户选择自己喜欢的字体。函数返回一个 QFont 对象,表示用户选择的字体
QFont font=QFontDialog::getFont(&ok,ui->textEdit->font(),this);
if(ok)
{
ui->textEdit->setFont(font);
}
}
void MainWindow::onContextMenuRequested(const QPoint &pos)
{
// 在位置弹出右键弹出式菜单
m_menu->exec(ui->textEdit->mapToGlobal(pos));
}
void MainWindow::showContextMenu()
{
// 给textEdit添加右键菜单
ui->textEdit->setContextMenuPolicy(Qt::CustomContextMenu);//当该Widget接收到鼠标右键点击事件时,根据设置的策略来确定是否显示上下文菜单。
connect(ui->textEdit, &QTextEdit::customContextMenuRequested, [=](const QPoint &pos){
QMenu *menu = new QMenu(this);
QAction *quitAction = new QAction("退出", this);
connect(quitAction, &QAction::triggered, [=](){
QApplication::quit();
});
menu->addAction(quitAction);
QAction *fontAction = new QAction("字体", this);
connect(fontAction, &QAction::triggered, [=](){
bool ok;
QFont selectedFont = QFontDialog::getFont(&ok, ui->textEdit->font(), this);
if (ok) {
ui->textEdit->setFont(selectedFont);
}
});
menu->addAction(fontAction);
menu->exec(ui->textEdit->mapToGlobal(pos));
delete menu;
});
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void openFile();
void saveFile();
void about();
void login();
void logout();
private:
Ui::MainWindow *ui;
QString m_currentFile;
QString m_softwareName;
QString m_author;
QString m_developmentDate;
QString m_username;
QToolBar *m_toolbar;
QMenu *m_menu;
void createActions();//初始状态
void createToolBars();//工具栏
//void createToolButtons();
void createStatusBar();//状态栏
void updateStatus();//更新状态栏
void createMenu();//创建右键弹出式菜单
//字体选择组合框
void onFontChanged(const QFont &font);//当字体选择组合框中的字体更改时,并设置为新字体
void onChooseFont();//弹出字体选择对话框,并设置为所选字体
void onContextMenuRequested(const QPoint &pos);//text位置弹出右键弹出式菜单
//右键菜单
void showContextMenu();
};
#endif // MAINWINDOW_H
Lab9
1.鼠标键盘事件练习
一、事件练习:
做一窗口,上面有一按钮(1)按下鼠标左键并拖动鼠标,按钮随着鼠标的光标移动,同时在状态栏显示鼠标以用户区坐标系表示的位置坐标;(2) 当输入焦点在窗口上时,按下键盘上的Ctrl同时按下M的时候,窗口最大化显示;(3)做弹出式菜单“窗口”,下面三个菜单项“最大”“最小”“普通”,要求菜单项需要有图标,图标自定,要求使用qt的资源;实现三个菜单项对应的功能;(4)在工具栏上添加上述三个菜单项所对应的Action。(5)在窗口上双击鼠标左键,窗口最大化,双击右键,由最大化恢复。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
#include
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
createMenu();//创建菜单
createToolBar();//创建工具栏
}
MainWindow::~MainWindow()
{
delete ui;
}
//鼠标左键点哪里按钮就到哪里
void MainWindow::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) //如果点击鼠标左键
{
ui->pushButton->move(event->pos());//按钮随鼠标移动
//状态栏显示
statusBar()->showMessage(QString("X: %1, Y: %2").arg(event->pos().x()).arg(event->pos().y()));
}
}
//按下鼠标左键,按钮跟着鼠标动
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton) //判断鼠标事件中是否包含左键按下的信号(判断是否拖拽鼠标左键)
{
ui->pushButton->move(event->pos());
statusBar()->showMessage(QString("X: %1, Y: %2").arg(event->pos().x()).arg(event->pos().y()));
}
}
void MainWindow::createMenu()
{
// 添加菜单栏
QMenu *windowMenu = new QMenu(tr("&Window"), this);
menuBar()->addMenu(windowMenu);
// 添加最大化菜单项
maximizeAction = new QAction(QIcon(":/images/bear.jpg"), tr("&Maximize"), this);
maximizeAction->setShortcut(tr("Ctrl+M"));
windowMenu->addAction(maximizeAction);
connect(maximizeAction, &QAction::triggered, this, &MainWindow::on_actionMaximize_triggered);
// 添加最小化菜单项
minimizeAction = new QAction(QIcon(":/images/car.jpg"), tr("&Minimize"), this);
windowMenu->addAction(minimizeAction);
connect(minimizeAction, &QAction::triggered, this, &MainWindow::on_actionMinimize_triggered);
// 添加普通菜单项
normalAction = new QAction(QIcon(":/images/cow.jpg"), tr("&Normal"), this);
windowMenu->addAction(normalAction);
connect(normalAction, &QAction::triggered, this, &MainWindow::on_actionNormal_triggered);
}
//实现窗口最大化
void MainWindow::on_actionMaximize_triggered()
{
setWindowState(windowState() | Qt::WindowMaximized);
}
//实现窗口最小化
void MainWindow::on_actionMinimize_triggered()
{
setWindowState(windowState() | Qt::WindowMinimized);
}
//正常窗口大小
void MainWindow::on_actionNormal_triggered()
{
setWindowState(windowState() & ~(Qt::WindowMaximized | Qt::WindowMinimized));
}
//创建工具栏
void MainWindow::createToolBar()
{
QToolBar *toolBar=new QToolBar(tr("Window"),this);//创建工具栏
addToolBar(toolBar);//toolBar工具栏添加到当前窗口中
toolBar->addAction(maximizeAction);//添加工具项
toolBar->addAction(minimizeAction);
toolBar->addAction(normalAction);
}
//双击鼠标左键,窗口最大化,双击右键,由最大化恢复
void MainWindow::mouseDoubleClickEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton) {
setWindowState(windowState() | Qt::WindowMaximized);
} else if (event->button() == Qt::RightButton) {
setWindowState(windowState() & ~Qt::WindowMaximized);
}
}
//按下键盘上的Ctrl同时按下M的时候,窗口最大化显示
void MainWindow::keyPressEvent(QKeyEvent *event)
{
//event->modifiers()用于获取用户按下的修饰键,Qt::ControlModifier表示"Ctrl"键。
if (event->key() == Qt::Key_M && event->modifiers() == Qt::ControlModifier) {
setWindowState(windowState() ^ Qt::WindowMaximized);//最大化显示
}
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
protected:
void mousePressEvent(QMouseEvent *event);//鼠标按下
void mouseMoveEvent(QMouseEvent *event);//鼠标移动
void keyPressEvent(QKeyEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
private slots:
void on_actionMaximize_triggered();
void on_actionMinimize_triggered();
void on_actionNormal_triggered();
private:
Ui::MainWindow *ui;
QAction *maximizeAction;//最大化菜单项
QAction *minimizeAction;//最小化菜单项
QAction *normalAction;//普通菜单项
void createToolBar();//创建工具栏
void createMenu();//创建菜单
};
#endif // MAINWINDOW_H
2.定时器和随机数
使用定时器可以在指定时间执行一些功能,而要实现随机效果就要使用随机数来实现。实验目标为新建程序实现电子时钟效果,并每隔一秒随机显示一张图片。
#include "widget.h"
#include "ui_widget.h"
#include
#include
#include
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
timer = new QTimer(this);
//关联定时器溢出信号和相应的槽函数
connect(timer, &QTimer::timeout, this, &Widget::timerUpdate);
}
Widget::~Widget()
{
delete ui;
}
void Widget::timerUpdate()
{
//获取系统现在的时间
QDateTime time = QDateTime::currentDateTime();
//设置系统时间显示格式
QString str = time.toString("yyyy-MM-dd hh:mm:ss dddd");
//在标签上显示时间
ui->lineEdit->setText(str);
int rand = QRandomGenerator::global()->bounded(5); // 产生5以内随机整数即0-4
//播放图片
QPixmap pix = QPixmap(QString(":/images/%1.JPG").arg(rand));
ui->label->setPixmap(pix.scaled(ui->label->size(), Qt::IgnoreAspectRatio));
}
//开始按钮
void Widget::on_pushButton_clicked()
{
timer->start(1000);
}
//结束按钮
void Widget::on_pushButton_2_clicked()
{
timer->stop();
}
#ifndef WIDGET_H
#define WIDGET_H
#include
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; class QTimer;}
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void timerUpdate();
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::Widget *ui;
QTimer *timer;
};
#endif // WIDGET_H
Lab10
1.鼠标绘图 按键缩放移动
1.创建一个简单窗口, 按下鼠标左键,拖动鼠标,在用户区上画出一个矩形,矩形左上角以初始按下鼠标的点,右下角为鼠标当前位置,放开鼠标,窗口用户区显示一个最后的矩形。按下键盘的‘l’(英文字母L的小写),矩形放大,按下‘s’键,矩形缩小,并能用方向键实现所画矩形按相应方向移动。
override
是C++11中的一个关键字,用于显式地指示一个虚函数是重写基类中的虚函数。它的作用是帮助程序员更好地理解代码。
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//设置初始窗口
setWindowTitle("Draw Rectangle");
setFixedSize(999, 999);
}
MainWindow::~MainWindow()
{
delete ui;
}
//鼠标点击
void MainWindow::mousePressEvent(QMouseEvent *event)
{
if(event->button()==Qt::LeftButton)
{
m_startPoint=event->pos();
m_endPoint=m_startPoint;
update();//更新绘图内容
}
}
//鼠标移动
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
if (event->buttons() & Qt::LeftButton)
{
m_endPoint = event->pos();
update();
}
}
//鼠标释放
void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
{
m_endPoint = event->pos();
update();
}
}
void MainWindow::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_L)//l放大
{
m_startPoint.setX(m_startPoint.x() - 5);
m_endPoint.setX(m_endPoint.x() + 5);
m_startPoint.setY(m_startPoint.y() - 5);
m_endPoint.setY(m_endPoint.y() + 5);
update();
}
else if (event->key() == Qt::Key_S)//s缩小
{
m_startPoint.setX(m_startPoint.x() + 5);
m_endPoint.setX(m_endPoint.x() - 5);
m_startPoint.setY(m_startPoint.y() + 5);
m_endPoint.setY(m_endPoint.y() - 5);
update();
}
else if (event->key() == Qt::Key_Left)
{
m_startPoint.setX(m_startPoint.x() - 10);
m_endPoint.setX(m_endPoint.x() - 10);
update();
}
else if (event->key() == Qt::Key_Right)
{
m_startPoint.setX(m_startPoint.x() + 10);
m_endPoint.setX(m_endPoint.x() + 10);
update();
}
else if (event->key() == Qt::Key_Up)
{
m_startPoint.setY(m_startPoint.y() - 10);
m_endPoint.setY(m_endPoint.y() - 10);
update();
}
else if (event->key() == Qt::Key_Down)
{
m_startPoint.setY(m_startPoint.y() + 10);
m_endPoint.setY(m_endPoint.y() + 10);
update();
}
}
//画图
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter painter(this);//定义画笔
painter.setPen(Qt::black);//画笔颜色
painter.drawRect(QRect(m_startPoint, m_endPoint).normalized());
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
protected:
void mousePressEvent(QMouseEvent *event) override;//鼠标点击
void mouseMoveEvent(QMouseEvent *event) override;//鼠标移动
void mouseReleaseEvent(QMouseEvent *event) override;//鼠标释放
void keyPressEvent(QKeyEvent *event) override;//按键
void paintEvent(QPaintEvent *event) override;//画图
private:
Ui::MainWindow *ui;
QPoint m_startPoint;//鼠标开始位置指针
QPoint m_endPoint;//鼠标结束位置指针
};
#endif // MAINWINDOW_H
2.按键绘图 按键变色
2.做一个简单的画图程序,基本功能:
1)按“L”后,用鼠标拖拽能在屏幕上画直线;
2)按“E”后,用鼠标托拽能在屏幕上画矩形
3)按“C”后,用鼠标拖拽能在屏幕上画圆
4)按“R”“G”“B”能够改变所画图形为红、绿、蓝色
5)对上述功能做菜单、工具栏和状态栏
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
protected:
void mousePressEvent(QMouseEvent *event);// 鼠标按下事件
void mouseMoveEvent(QMouseEvent *event);// 鼠标移动事件
void mouseReleaseEvent(QMouseEvent *event);// 鼠标释放事件
void paintEvent(QPaintEvent *event);// 绘图事件
void keyPressEvent(QKeyEvent *event);// 键盘事件
private slots:
void setLineColorRed();// 将线条颜色设置为红色
void setLineColorGreen();// 将线条颜色设置为绿色
void setLineColorBlue();// 将线条颜色设置为蓝色
void PaintChoose();//形状选择
private:
Ui::MainWindow *ui;
enum ShapeType { Line, Rectangle, Ellipse };// 定义图形类型枚举类
ShapeType currentShape;// 当前绘制的图形类型
bool drawing;// 是否正在绘图
QPoint startPoint;// 绘制开始点
QPoint endPoint;// 绘制结束点
QColor lineColor;// 线条颜色
QMenuBar *menuBar;// 菜单栏
QToolBar *toolBar;// 工具栏
QStatusBar *statusBar;// 状态栏
QLabel *statusLabel;// 状态栏标签
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
setFixedSize(999, 999);
currentShape = Line;
drawing = false;
lineColor = Qt::black;
// 创建菜单栏
menuBar = new QMenuBar(this);
QMenu *fileMenu = menuBar->addMenu(tr("&File"));
QAction *exitAction = fileMenu->addAction(tr("&Exit"), this, &QWidget::close);
QMenu *shapeMenu = menuBar->addMenu(tr("&Shape"));
QAction *lineAction = shapeMenu->addAction(tr("&Line"), [this]() {currentShape = Line;});
QAction *rectAction = shapeMenu->addAction(tr("&Rectangle"), [this]() {currentShape = Rectangle;});
QAction *ellipseAction = shapeMenu->addAction(tr("&Ellipse"), [this]() {currentShape = Ellipse;});
// 创建工具栏
toolBar = new QToolBar(this);
toolBar->addAction(lineAction);
toolBar->addAction(rectAction);
toolBar->addAction(ellipseAction);
// 创建状态栏
statusBar = new QStatusBar(this);
statusLabel = new QLabel(statusBar);
statusLabel->setText(tr("Ready"));
//加入主窗口
setMenuBar(menuBar);
addToolBar(toolBar);
setStatusBar(statusBar);
connect(exitAction, &QAction::triggered, this, &QWidget::close); // 退出程序
}
MainWindow::~MainWindow()
{
delete ui;
}
// 鼠标按下事件
void MainWindow::mousePressEvent(QMouseEvent *event)
{
if(event->button()==Qt::LeftButton)
{
startPoint = event->pos();
endPoint = event->pos();
drawing = true;//按下后表示开始绘画
}
}
// 鼠标移动事件
void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
if ((event->buttons() & Qt::LeftButton) && drawing) {
endPoint = event->pos();
update(); // 触发绘图事件
}
}
// 鼠标释放事件
void MainWindow::mouseReleaseEvent(QMouseEvent *event)
{
if(event->button()==Qt::LeftButton && drawing)
{
endPoint=event->pos();
drawing=false;
update();
}
}
// 绘图事件
void MainWindow::paintEvent(QPaintEvent *event)
{
//告诉编译器忽略未使用的变量或参数。
//在这里,"event"是一个未使用的参数,在函数中没有被使用,但为了满足函数参数的要求而被保留。
Q_UNUSED(event);
QPainter painter(this);
//设置画笔颜色、线宽和样式
painter.setPen(QPen(lineColor,2,Qt::SolidLine,Qt::RoundCap));
//选择图形
switch(currentShape)
{
case Line:
painter.drawLine(startPoint,endPoint);
break;
case Rectangle:
painter.drawRect(QRect(startPoint,endPoint));
break;
case Ellipse:
painter.drawEllipse(QRect(startPoint,endPoint));
break;
}
}
void MainWindow::PaintChoose()
{
QPainter painter(this);
painter.setPen(QPen(lineColor, 2, Qt::SolidLine, Qt::RoundCap)); // 设置画笔颜色、线宽和样式
switch (currentShape) {
case Line:
painter.drawLine(startPoint, endPoint); // 画直线
break;
case Rectangle:
painter.drawRect(QRect(startPoint, endPoint)); // 画矩形
break;
case Ellipse:
painter.drawEllipse(QRect(startPoint, endPoint)); // 画椭圆
break;
}
}
//改变状态栏
void MainWindow::setLineColorRed()
{
lineColor = Qt::red; // 将线条颜色设置为红色
statusLabel->setText(tr("Red line")); // 修改状态栏标签文本
}
void MainWindow::setLineColorGreen()
{
lineColor = Qt::green; // 将线条颜色设置为绿色
statusLabel->setText(tr("Green line")); // 修改状态栏标签文本
}
void MainWindow::setLineColorBlue()
{
lineColor = Qt::blue; // 将线条颜色设置为蓝色
statusLabel->setText(tr("Blue line")); // 修改状态栏标签文本
}
void MainWindow::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_R)
{
setLineColorRed();
PaintChoose();
update();
}
else if (event->key() == Qt::Key_G)
{
setLineColorGreen();
PaintChoose();
update();
}
else if (event->key() == Qt::Key_B)
{
setLineColorBlue();
PaintChoose();
update();
}
else if (event->key() == Qt::Key_L)
{
currentShape=Line;
PaintChoose();
update();
}
else if (event->key() == Qt::Key_E)
{
currentShape=Rectangle;
PaintChoose();
update();
}
else if (event->key() == Qt::Key_C)
{
currentShape=Ellipse;
PaintChoose();
update();
}
}
Lab11
1.布局设计
Test3(30分)signer进行布局设计
(3)定义一个名为Person的结构体, 包括以下几个成员:
QString name, int sex, int age, QString description
要求:用户输入的年龄范围在(20-30)
(4)单击“Add”按钮,完成如下事情:1. 检查姓名、描述是否为空,如果是空的,弹出一个对话框,提示哪项不能为空;2. 如果检查通过了,则根据用户输入生成一个Person数据,保存到一个链表std::list中。(10分)
(5)单击“Show”按钮,完成如下事情:1. 弹出一个对话框,对话框与上图相同,只是按钮名分别为“Pre”和“Next”;2. 刚弹出时,对话框中显示存储在链表中的第一条记录;3. 按下“Pre”和“Next”按钮,对话框分别显示当前记录的前一条和后一条记录信息。(15分)
#include "widget.h"
#include "ui_widget.h"
#include
#include //垂直布局
#include //水平布局
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_add_clicked()
{
//获取数据
QString name=ui->lineEdit_name->text();
QString description=ui->lineEdit_desc->text();
int sex=ui->comboBox_sex->currentIndex();//返回当前的标签索引值
int age=ui->spinBoxage->value();
if(name.isEmpty())
{
QMessageBox::warning(this,"Warning","Name can't be empty");
return;
}
if(description.isEmpty())
{
QMessageBox::warning(this,"Warning","Description can't be empty");
return;
}
//加入链表
Person person={name,sex,age,description};
m_personList.push_back(person);
QMessageBox::information(this,"Information","Person added");
}
void Widget::on_pushButton_show_clicked()
{
if(m_personList.empty())
{
QMessageBox::warning(this,"Warning","No person added.");
return;
}
//创建新窗口
QDialog *dialog=new QDialog(this);
dialog->setWindowTitle("Person");
nameLabel = new QLabel("Name:");
sexLabel = new QLabel("Sex:");
ageLabel = new QLabel("Age:");
descriptionLabel = new QLabel("Description:");
nameValueLabel = new QLabel();
sexValueLabel = new QLabel();
ageValueLabel = new QLabel();
descriptionValueLabel = new QLabel();
preButton = new QPushButton("Pre");
nextButton = new QPushButton("Next");
QHBoxLayout* nameLayout = new QHBoxLayout();
nameLayout->addWidget(nameLabel);
nameLayout->addWidget(nameValueLabel);
QHBoxLayout* sexLayout = new QHBoxLayout();
sexLayout->addWidget(sexLabel);
sexLayout->addWidget(sexValueLabel);
QHBoxLayout* ageLayout = new QHBoxLayout();
ageLayout->addWidget(ageLabel);
ageLayout->addWidget(ageValueLabel);
QHBoxLayout* descriptionLayout = new QHBoxLayout();
descriptionLayout->addWidget(descriptionLabel);
descriptionLayout->addWidget(descriptionValueLabel);
QHBoxLayout* buttonLayout = new QHBoxLayout();
buttonLayout->addStretch();
buttonLayout->addWidget(preButton);
buttonLayout->addWidget(nextButton);
QVBoxLayout* mainLayout = new QVBoxLayout();
mainLayout->addLayout(nameLayout);
mainLayout->addLayout(sexLayout);
mainLayout->addLayout(ageLayout);
mainLayout->addLayout(descriptionLayout);
mainLayout->addLayout(buttonLayout);
dialog->setLayout(mainLayout);
m_currentPerson = m_personList.begin();//从第一条开始
//设置文本
nameValueLabel->setText(m_currentPerson->name);
sexValueLabel->setText(m_currentPerson->sex == 0 ? "Male" : "Female");
ageValueLabel->setText(QString::number(m_currentPerson->age));
descriptionValueLabel->setText(m_currentPerson->description);
//int current=std::distance(m_personList.begin(),m_currentPerson);
if (m_personList.size() == 1) {
preButton->setEnabled(false);
nextButton->setEnabled(false);
}
else {
preButton->setEnabled(false);
nextButton->setEnabled(true);
}
connect(preButton, &QPushButton::clicked, this, &Widget::onPreButtonClicked);
connect(nextButton, &QPushButton::clicked, this, &Widget::onNextButtonClicked);
dialog->exec();
}
void Widget::onPreButtonClicked()
{
m_currentPerson--;
nameValueLabel->setText(m_currentPerson->name);
sexValueLabel->setText(m_currentPerson->sex == 0 ? "Male" : "Female");
ageValueLabel->setText(QString::number(m_currentPerson->age));
descriptionValueLabel->setText(m_currentPerson->description);
preButton->setEnabled(m_currentPerson != m_personList.begin());
nextButton->setEnabled(true);
}
void Widget::onNextButtonClicked()
{
m_currentPerson++;
nameValueLabel->setText(m_currentPerson->name);
sexValueLabel->setText(m_currentPerson->sex == 0 ? "Male" : "Female");
ageValueLabel->setText(QString::number(m_currentPerson->age));
descriptionValueLabel->setText(m_currentPerson->description);
preButton->setEnabled(true);
nextButton->setEnabled(m_currentPerson != --m_personList.end());
}
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
#include
#include
struct Person{
QString name;
int sex;
int age;
QString description;
};
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_pushButton_add_clicked();
void on_pushButton_show_clicked();
void onPreButtonClicked();
void onNextButtonClicked();
private:
Ui::Widget *ui;
QListm_personList;
QList::iterator m_currentPerson;//迭代器
//新界面变量
QLabel* nameLabel;
QLabel* sexLabel;
QLabel* ageLabel;
QLabel* descriptionLabel;
QLabel* nameValueLabel;
QLabel* sexValueLabel;
QLabel* ageValueLabel;
QLabel* descriptionValueLabel;
QPushButton* preButton;
QPushButton* nextButton;
};
#endif // WIDGET_H
2.菜单
Test4(20分) MainWindow与菜单 (20)
(6)建立一个以QMainWindow为窗口的项目Project_2
(7)在Designer中,增加一个菜单File,并在其中加入三个菜单项:New, Save, Exit;进一步,在工具栏中放入上述三个菜单项对应的Action (5分)
(8)在窗口中放入一个QPlainTextEdit部件
当单击New菜单时,清空QPlainTextEdit中的内容;当单击Save菜单时,把QPlainTextEdit中的内容保存到一个用户指定的文本文件中。(15分)
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 将槽函数与菜单项的点击事件关联
connect(ui->actionNew, &QAction::triggered, this, &MainWindow::on_actionNew_triggered);
connect(ui->actionSave, &QAction::triggered, this, &MainWindow::on_actionSave_triggered);
connect(ui->actionExit, &QAction::triggered, this, &MainWindow::on_actionExit_triggered);
}
MainWindow::~MainWindow()
{
delete ui;
}
// 槽函数,清空QPlainTextEdit中的内容
void MainWindow::on_actionNew_triggered()
{
ui->plainTextEdit->clear();
}
// 槽函数,将QPlainTextEdit中的内容保存到用户指定的文本文件中
void MainWindow::on_actionSave_triggered()
{
// 获取保存文件的路径
QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "", tr("Text Files (*.txt)"));
// 如果用户选择了保存文件的路径,则执行保存操作
if (fileName != "") {
QFile file(fileName);
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream stream(&file);
stream << ui->plainTextEdit->toPlainText(); // 将QPlainTextEdit中的内容写入文件
file.close();
}
}
}
// 槽函数,退出应用程序
void MainWindow::on_actionExit_triggered()
{
QApplication::quit();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_actionNew_triggered();
void on_actionSave_triggered();
void on_actionExit_triggered();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
n>
struct Person{
QString name;
int sex;
int age;
QString description;
};
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_pushButton_add_clicked();
void on_pushButton_show_clicked();
void onPreButtonClicked();
void onNextButtonClicked();
private:
Ui::Widget ui;
QListm_personList;
QList::iterator m_currentPerson;//迭代器
//新界面变量
QLabel nameLabel;
QLabel* sexLabel;
QLabel* ageLabel;
QLabel* descriptionLabel;
QLabel* nameValueLabel;
QLabel* sexValueLabel;
QLabel* ageValueLabel;
QLabel* descriptionValueLabel;
QPushButton* preButton;
QPushButton* nextButton;
};
#endif // WIDGET_H
### 2.菜单
Test4(20分) MainWindow与菜单 (20)
(6)建立一个以QMainWindow为窗口的项目Project_2
(7)在Designer中,增加一个菜单File,并在其中加入三个菜单项:New, Save, Exit;进一步,在工具栏中放入上述三个菜单项对应的Action (5分)
(8)在窗口中放入一个QPlainTextEdit部件
当单击New菜单时,清空QPlainTextEdit中的内容;当单击Save菜单时,把QPlainTextEdit中的内容保存到一个用户指定的文本文件中。(15分)
```c++
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 将槽函数与菜单项的点击事件关联
connect(ui->actionNew, &QAction::triggered, this, &MainWindow::on_actionNew_triggered);
connect(ui->actionSave, &QAction::triggered, this, &MainWindow::on_actionSave_triggered);
connect(ui->actionExit, &QAction::triggered, this, &MainWindow::on_actionExit_triggered);
}
MainWindow::~MainWindow()
{
delete ui;
}
// 槽函数,清空QPlainTextEdit中的内容
void MainWindow::on_actionNew_triggered()
{
ui->plainTextEdit->clear();
}
// 槽函数,将QPlainTextEdit中的内容保存到用户指定的文本文件中
void MainWindow::on_actionSave_triggered()
{
// 获取保存文件的路径
QString fileName = QFileDialog::getSaveFileName(this, tr("Save File"), "", tr("Text Files (*.txt)"));
// 如果用户选择了保存文件的路径,则执行保存操作
if (fileName != "") {
QFile file(fileName);
if (file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QTextStream stream(&file);
stream << ui->plainTextEdit->toPlainText(); // 将QPlainTextEdit中的内容写入文件
file.close();
}
}
}
// 槽函数,退出应用程序
void MainWindow::on_actionExit_triggered()
{
QApplication::quit();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_actionNew_triggered();
void on_actionSave_triggered();
void on_actionExit_triggered();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
你可能感兴趣的:(Qt,qt,开发语言)