六、标准对话框、多应用窗体

news2024/11/27 8:23:55

一、标准对话框

Qt提供了一些常用的标准对话框,如打开文件对话框、选择颜色对话框、信息提示和确认选择对话框、标准输入对话框等。

1、预定义标准对话框

(1)QFileDialog 文件对话框

  • QString getOpenFileName() 打开一个文件
  • QstringList getOpenFileNames() 打开多个文件
  • QString getSaveFileName() 选择保存一个文件
  • QString getExistingDirectory() 选择一个已有目录
  • QUrl getOpenFileUrl() 打开一个网络文件

(2)QColorDialog 颜色对话框

  • QColor getColor() 选择颜色

(3)QFontDialog 选择字体

  • QFont getFont() 选择字体

(4)QInputDialog 输入对话框

  • QString getText() 的呼入单行文字
  • int getInt() 输入整数
  • double getDouble() 输入浮点数
  • QString getItem() 从一个下拉列表中选择输入
  • QString getMultiLineText() 输入多行字符串

(5)QMessageBox 消息对话框

  • StandardButton information() 信息提示对话框
  • StandardButton question() 询问并获取是否确定对话框
  • StandardButton warning() 警告信息提示对话框
  • StandardButton critical() 错误信息提示对话框
  • void about() 设置自定义信息的关于对话框
  • void aboutQt() 关于Qt的对话框

2、实现工具

(1)创建项目,基于QDialog

(2)添加组件

在这里插入图片描述

(3)实现信号与槽

#include "dialog.h"
#include "ui_dialog.h"

#include <QFileDialog>
#include <QColorDialog>
#include <QFontDialog>
#include <QInputDialog>
#include <QMessageBox>


Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);
}

Dialog::~Dialog()
{
    delete ui;
}

void Dialog::on_btnClearText_clicked()
{
    ui->plainTextEdit->clear();
}

void Dialog::on_btnOpenFile_clicked()
{
    QString strCurPath = QDir::currentPath();
    QString strTitle = "选择文件对话框";
    QString strFilter = "文本文件(*.txt);;图片文件(*.ipg *.png);;所有格式(*.*)";  // 文件选择过滤器
    QString strFileName = QFileDialog::getOpenFileName(this, strTitle, strCurPath,
                          strFilter);

    if(strFileName.isEmpty())
    {
        return;
    }

    ui->plainTextEdit->appendPlainText(strFileName);
}

void Dialog::on_btnOpenFiles_clicked()
{
    QString strCurPath = QDir::currentPath();
    QString strTitle = "选择文件对话框";
    QString strFilter = "文本文件(*.txt);;图片文件(*.ipg *.png);;所有格式(*.*)";  // 文件选择过滤器
    QStringList FileNames = QFileDialog::getOpenFileNames(this, strTitle, strCurPath,
                            strFilter);

    if(FileNames.count() == 0)
    {
        return;
    }

    foreach (QString strFileName, FileNames)
    {
        ui->plainTextEdit->appendPlainText(strFileName);
    }
}

void Dialog::on_btnSelectDir_clicked()
{
    QString strCurPath = QDir::currentPath();
    QString strTitle = "选择文件对话框";
    QString strSelectDir = QFileDialog::getExistingDirectory(this, strTitle, strCurPath,
                           QFileDialog::ShowDirsOnly);

    if(strSelectDir.isEmpty())
    {
        return;
    }

    ui->plainTextEdit->appendPlainText(strSelectDir);
}

void Dialog::on_btnSaveFile_clicked()
{
    QString strCurPath = QCoreApplication::applicationDirPath();
    QString strTitle = "选择文件对话框";
    QString strFilter = "文本文件(*.txt);;图片文件(*.ipg *.png);;所有格式(*.*)";  // 文件选择过滤器
    QString strFileName = QFileDialog::getSaveFileName(this, strTitle, strCurPath,
                          strFilter);

    if(strFileName.isEmpty())
    {
        return;
    }

    ui->plainTextEdit->appendPlainText(strFileName);
}


void Dialog::on_btnSelectColor_clicked()
{
    QPalette pal = ui->plainTextEdit->palette();
    QColor initColor = pal.color(QPalette::Text);
    QColor color = QColorDialog::getColor(initColor, this, "选择颜色");

    if(!color.isValid())
    {
        return;
    }

    pal.setColor(QPalette::Text, color);
    ui->plainTextEdit->setPalette(pal);
}

void Dialog::on_btnSelectFont_clicked()
{
    bool ok = false;
    QFont initFont = ui->plainTextEdit->font();
    QFont font = QFontDialog::getFont(&ok, initFont, this, "选择字体");

    if(!ok)
    {
        return;
    }

    ui->plainTextEdit->setFont(font);
}

void Dialog::on_btnInputString_clicked()
{
    QString strTitle = "输入文字对话框";
    QString strLabel = "请输入文字";
    QString strDefault = "默认文字";
    QLineEdit::EchoMode echoMode = QLineEdit::Normal;
    bool ok = false;
    QString str = QInputDialog::getText(this, strTitle, strLabel,
                                        echoMode, strDefault, &ok);

    if(!ok)
    {
        return;
    }

    ui->plainTextEdit->appendPlainText(str);
}

void Dialog::on_btnInputInt_clicked()
{
    QString strTitle = "输入整数对话框";
    QString strLabel = "请输入数字";
    int nDefault = ui->plainTextEdit->font().pointSize();
    int nMinValue = 0, nMaxValue = 100;
    bool ok = false;
    int nValue = QInputDialog::getInt(this, strTitle, strLabel, nDefault,
                                      nMinValue, nMaxValue, 1, &ok);

    if(!ok)
    {
        return;
    }

    QFont font = ui->plainTextEdit->font();
    font.setPointSize(nValue);
    ui->plainTextEdit->setFont(font);
    ui->plainTextEdit->appendPlainText(QString::asprintf("输入整数:%d", nValue));
}

void Dialog::on_btnInputFloat_clicked()
{
    QString strTitle = "输入整数对话框";
    QString strLabel = "请输入数字";
    double dDefault = 10.123;
    double dMinValue = 0.0, dMaxValue = 100.0;
    bool ok = false;
    double dValue = QInputDialog::getDouble(this, strTitle, strLabel, dDefault,
                                            dMinValue, dMaxValue, 3, &ok);

    if(!ok)
    {
        return;
    }

    ui->plainTextEdit->appendPlainText(QString::asprintf("输入整数:%.3lf", dValue));
}

void Dialog::on_btnInputSelect_clicked()
{
    QStringList items;
    items << "条目1" << "条目2" << "条目3" << "条目4";
    QString strTitle = "输入条目对话框";
    QString strLabel = "请选择一个条目";
    bool ok = false;
    QString str = QInputDialog::getItem(this, strTitle, strLabel, items, 0,
                                        true, &ok);

    if(!ok || str.isEmpty())
    {
        return;
    }

    ui->plainTextEdit->appendPlainText(str);
}

void Dialog::on_btnQuestion_clicked()
{
    QString strTitle = "Question消息框";
    QString strLabel = "选择是与否";
    QMessageBox::StandardButton result = QMessageBox::question(this, strTitle, strLabel,
                                         QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
                                         QMessageBox::Cancel);

    if(result == QMessageBox::Yes)
    {
        ui->plainTextEdit->appendPlainText("Yes");
    }
    else if (result == QMessageBox::No)
    {
        ui->plainTextEdit->appendPlainText("No");
    }
    else if (result == QMessageBox::Cancel)
    {
        ui->plainTextEdit->appendPlainText("Cancel");
    }
}

void Dialog::on_btnInformation_clicked()
{
    QMessageBox::information(this, "Information对话框", "信息", QMessageBox::Ok);
}

void Dialog::on_btnWarning_clicked()
{
    QMessageBox::warning(this, "Warning对话框", "警告", QMessageBox::Ok);
}

void Dialog::on_btnCritical_clicked()
{
    QMessageBox::critical(this, "Critical对话框", "错误", QMessageBox::Ok);
}

void Dialog::on_btnAbout_clicked()
{
    QMessageBox::about(this, "About对话框", "关于");
}

void Dialog::on_btnAboutQt_clicked()
{
    QMessageBox::aboutQt(this, "About对话框");
}

二、自定义标准对话框

1、实现工具

  • QWDialogSize 设置表格行列数对话框
  • QWDialogHeaders 设置表头对话框
  • QWDialogLocate 单元格定位于文字设置对话框
    在这里插入图片描述

(1)创建项目,基于QMainWindow

(2)添加组件

在这里插入图片描述

#include "qdialogsetsize.h"
#include "ui_qdialogsetsize.h"

#include <QMessageBox>

int QDialogSetSize::rowCount()
{
    return ui->spinBoxRow->value();
}

int QDialogSetSize::columnCount()
{
    return ui->spinBoxColumn->value();
}

void QDialogSetSize::setRowColumns(int nRow, int nColumn)
{
    ui->spinBoxRow->setValue(nRow);
    ui->spinBoxColumn->setValue(nColumn);
}

QDialogSetSize::QDialogSetSize(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::QDialogSetSize)
{
    ui->setupUi(this);
}

QDialogSetSize::~QDialogSetSize()
{
    QMessageBox::information(this, "", "设置大小对话框已经退出");
    delete ui;
}

(3)添加设置表格行列数UI于类

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

(4)添加设置表头的UI与类

在这里插入图片描述

#include "qdialogsetheaders.h"
#include "ui_qdialogsetheaders.h"

QDialogSetHeaders::QDialogSetHeaders(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::QDialogSetHeaders)
{
    ui->setupUi(this);

    theModel = new QStringListModel(this);
    ui->listView->setModel(theModel);
}

QDialogSetHeaders::~QDialogSetHeaders()
{
	QMessageBox::information(this, "", "设置表头对话框退出");
    delete ui;
}

void QDialogSetHeaders::setStringList(QStringList strList)
{
    theModel->setStringList(strList);
}

QStringList QDialogSetHeaders::getStringList()
{
    return theModel->stringList();
}

(5)添加定位单元格UI与类

在这里插入图片描述

#include "qdialoglocate.h"
#include "ui_qdialoglocate.h"
#include <QMessageBox>

QDialogLocate::QDialogLocate(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::QDialogLocate)
{
    ui->setupUi(this);
}

QDialogLocate::~QDialogLocate()
{
    QMessageBox::information(this, "", "单元格定位对话框退出");
    delete ui;
}

void QDialogLocate::setRange(int nRow, int nColumn)
{
    ui->spinBoxRow->setRange(0, nRow - 1);
    ui->spinBoxCol->setRange(0, nColumn - 1);
}

void QDialogLocate::setValue(int nRow, int nColumn)
{
    ui->spinBoxRow->setValue(nRow);
    ui->spinBoxCol->setValue(nColumn);
}

#include <mainwindow.h>
void QDialogLocate::closeEvent(QCloseEvent *event)
{
    Q_UNUSED(event)
    MainWindow *parent = (MainWindow*)parentWidget();
    parent->setActLocateEnable(true);
    parent->resetDlgLocate();
}

void QDialogLocate::on_btnSetText_clicked()
{
    int row = ui->spinBoxRow->value();
    int col = ui->spinBoxCol->value();
    MainWindow *parent = (MainWindow*)parentWidget();
    parent->setCelltext(row, col, ui->lineEdit->text());

    if(ui->checkBoxAddRow->isChecked())
    {
        ui->spinBoxRow->setValue(ui->spinBoxRow->value() + 1);
    }

    if(ui->checkBoxAddCol->isChecked())
    {
        ui->spinBoxCol->setValue(ui->spinBoxCol->value() + 1);
    }

}

(6)设置主程序功能

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QMessageBox>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    theModel = new QStandardItemModel(this);
    theSelect = new QItemSelectionModel(theModel);

    ui->tableView->setModel(theModel);
    ui->tableView->setSelectionModel(theSelect);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::setActLocateEnable(bool enable)
{
    ui->actLocate->setEnabled(enable);
}

void MainWindow::resetDlgLocate()
{
    dialogLocate = nullptr;
}

void MainWindow::setCelltext(int row, int col, QString strText)
{
    QModelIndex index = theModel->index(row, col);
    theModel->setData(index, strText, Qt::DisplayRole);
    theSelect->clearSelection();
    theSelect->setCurrentIndex(index, QItemSelectionModel::Select);
}

#include "qdialogsetsize.h"
void MainWindow::on_actSetSize_triggered()
{
    QDialogSetSize *dlg = new QDialogSetSize(this);
    dlg->setRowColumns(theModel->rowCount(), theModel->columnCount());
    int ret = dlg->exec();

    if(ret == QDialog::Accepted)
    {
        int row = dlg->rowCount();
        int col = dlg->columnCount();
        theModel->setRowCount(row);
        theModel->setColumnCount(col);
    }

    delete dlg;
}


void MainWindow::on_actSetHeader_triggered()
{
    if(nullptr == dialogHeader)
    {
        dialogHeader = new QDialogSetHeaders(this);
    }



    if(dialogHeader->getStringList().count() != theModel->columnCount())
    {
        QStringList strList;

        for (int i = 0; i < theModel->columnCount(); ++i)
        {
            strList << theModel->headerData(i, Qt::Horizontal).toString();
        }

        dialogHeader->setStringList(strList);
    }

    int ret = dialogHeader->exec();

    if(ret == QDialog::Accepted)
    {
        QStringList strList = dialogHeader->getStringList();
        theModel->setHorizontalHeaderLabels(strList);
    }
}

void MainWindow::on_actLocate_triggered()
{
    ui->actLocate->setEnabled(false);

    if(nullptr == dialogLocate)
    {
        dialogLocate = new QDialogLocate(this);
    }

    dialogLocate->setAttribute(Qt::WA_DeleteOnClose); //关闭自动删除
    Qt::WindowFlags flags = dialogLocate->windowFlags();
    dialogLocate->setWindowFlags(flags | Qt::WindowCloseButtonHint); //置于主界面上层

    dialogLocate->setRange(theModel->rowCount(), theModel->columnCount());
    QModelIndex curIndex = theSelect->currentIndex();

    if(curIndex.isValid())
    {
        dialogLocate->setValue(curIndex.row(), curIndex.column());
    }

    dialogLocate->show();
}

void MainWindow::on_tableView_clicked(const QModelIndex &index)
{
    if(dialogLocate != nullptr)
    {
        dialogLocate->setValue(index.row(), index.column());
    }
}

三、多窗体应用程序设计

1、视图类

  • QWidget:在没有指定父容器时,可以作为独立的窗口,指定父容器后可以作为容器的内部组件
  • QDialog:设计对话框,以独立窗口显示
  • QMainWindow:用于设计带有菜单栏、工具栏、状态栏的主窗口,一般独立窗口显示。
  • QSplashScreen:用作应用程序启动时的splash窗口,没有边框。
  • QMdiSubWindow:用于为QMdiArea提供一个子窗体,用于MDI(多文档)的设计。
  • QDesktopWidget:具有多个显卡和多个显示器的系统具有多个左面,这个类提供用户桌面信息,如屏幕个数,每个屏幕的大小等。
    QWindow:通过底层的窗口系统表示一个窗口类,一般作为一个父容器的嵌入式窗体,不作为独立窗体。
QObject
	QWidget
		QDialog
		QMainWindow
		QSplashScreen
		QMdiSubWindow
		QDesktopWidget
	QWindow

2、窗体特性

(1)设置运行特性和显示特性

void QWidget::setWindowState(Qt::WindowStates windowstate)
	Qt::NonModal 无模态,不会阻止其他窗体的输入
	Qt::WindowModal 窗口对于其父窗口、所有的商机父窗口都是模态的
	Qt::ApplicationModal 窗口对整个应用程序时模态的,阻止所有窗口的输入
void QWidget::setWindowOpacity(qreal level)
	参数level是1.0(完全不透明)至0.0(完全透明)之间的数。窗口透明度缺省值为1.0,即完全不透明。
void QWidgwt::setAttribute(Qt::WidgwtAttribute attribute, bool on = true)
	Qt::WA_AcceptDrops	允许窗体接受拖拽来的组件
	Qt::WA_DeleteOnClose	窗体关闭时删除自己,释放内存
	Qt::WA_Hover	鼠标进入或移除窗体时产生paint事件
	Qt::WA_AcceptTouchEvents	窗体是否接受触屏事件
表示窗体类型
void QWidget::setWindowFlags(Qt::WindowFlags type)
	Qt::Widget	这是QWidget类的缺省类型,如果有父窗体,就作为父窗体的子窗体,否则就作为一个独立的窗口
	Qt::Window	表明这个窗体是一个窗口,通常具有窗口的边框、标题栏,而不管它是都有父窗体
	Qt::Dialog	表明窗体是一个窗口,并且要显示为对话框(如:没有标题栏、没笑最小化、最大化),这是QDialog类的缺省类型
	Qt::Popup	表明扯个窗体是用作弹出式菜单的窗体
	Qt::Tool	表明这个窗体是工具窗体,具有更小的标题栏和关闭按钮,通常作为工具栏的窗体
	Qt::ToolTip	表明这是用于ToolTip消息提示的窗体
	Qt::SplashScreen	表明窗体是Splash屏幕,是QSplashScreen类的缺省类型
	Qt::DeskTop	表明窗体时桌面,这是QDesktopWidget类的类型
	Qt::SubWindow	表明窗体是子窗体,例如QMdiSubWindow就是这种类型
控制窗体显示效果
	Qt::MSWindowsFisedSizeDialogHint	在WIndows平台上,是的窗口具有更窄的边框
	Qt::FramelessWindowHint		创建无边框窗口
QindowHint要行医窗体外观定制窗体外观的常量,需要先设置Qt::Customize
	Qt::CustmizeWindowHint	关闭缺省的窗口标题栏
	Qt::WindowTitleHint		窗口有标题栏
	Qt::WindowSystemMenuHint	有窗口系统菜单
	Qt::WindowMinimizeButtonHint	有最小化按钮
	Qt::WindowMaximizeButtonHint	有最大化按钮
	Qt::WindowMinMaxButtonHint	有最小化、最大化按钮
	Qt::WindowCloseButtonHint	有关闭按钮
	Qt::wContextHelpButtonHint	有上下文帮助按钮
	Qt::WindowStaysOnTopHint	窗口总是处于最上层
	Qt::WindowStaysOnBottomHint	窗口总是处于最下层
	Qt::WindowtransparentForInput	窗口只作为输出,不接受输入	

3、实现工具

(1)创建项目,基于QMainWindow

(2)添加源文件图标

(3)添加工具栏

在这里插入图片描述
在这里插入图片描述

(4)添加UI界面

在这里插入图片描述

(5)实现功能

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    setCentralWidget(ui->tabWidget);
    ui->tabWidget->setVisible(false);   //不显示

}

MainWindow::~MainWindow()
{
    delete ui;
}

#include <QPainter>
void MainWindow::paintEvent(QPaintEvent *event)
{
    // 使用图片绘制底板
    Q_UNUSED(event)
    QPainter painter(this);
    painter.drawPixmap(0, ui->mainToolBar->height(), width(),
                       height() - ui->mainToolBar->height() - ui->statusBar->height(),
                       QPixmap(":/images/images/back.jpg"));
}

#include "formdoc.h"
void MainWindow::on_actWidgetInsite_triggered()
{
    FormDoc *formDoc = new FormDoc(this);
    formDoc->setAttribute(Qt::WA_DeleteOnClose);
    int cur = ui->tabWidget->addTab(formDoc, QString::asprintf("Doc %d", ui->tabWidget->count()));
    ui->tabWidget->setCurrentIndex(cur);
    ui->tabWidget->setVisible(true);
}

void MainWindow::on_tabWidget_tabCloseRequested(int index)
{
    if(index < 0)
    {
        return;
    }

    QWidget* tab = ui->tabWidget->widget(index);
    tab->close();
}

void MainWindow::on_tabWidget_currentChanged(int index)
{
    Q_UNUSED(index)

    if(ui->tabWidget->count() == 0)
    {
        ui->tabWidget->setVisible(false);
    }
}

void MainWindow::on_actWidget_triggered()
{
    FormDoc *formDoc = new FormDoc();
    formDoc->setAttribute(Qt::WA_DeleteOnClose);
    formDoc->setWindowTitle("Widget独立窗口");
    formDoc->setWindowOpacity(0.7); //半透明
    formDoc->show();
}

#include "formtable.h"
void MainWindow::on_actMainWindowInsite_triggered()
{
    FormTable *formtable = new FormTable(this);
    formtable->setAttribute(Qt::WA_DeleteOnClose);
    int cur = ui->tabWidget->addTab(formtable, QString::asprintf("Table %d", ui->tabWidget->count()));
    ui->tabWidget->setCurrentIndex(cur);
    ui->tabWidget->setVisible(true);
}

void MainWindow::on_actMainWindow_triggered()
{
    FormTable *formtable = new FormTable(this);
    formtable->setAttribute(Qt::WA_DeleteOnClose);
    formtable->setWindowTitle("MainWindow独立窗口");
    formtable->setWindowOpacity(0.7); //半透明
    formtable->show();
}

四、MDI应用程序设计

QMdiArea(Multiple Document Interface Area)提供一个可以同时显示多个文档窗口的区域。区域本身是一个框架,每个窗口是都一个QMdiSubWindow对象。
设置MDI视图窗口模式用setViewMode()函数,有两种选择:
setViewMode()
	QMdiArea::SubWindowView	传统的子窗口模式
	WMdiArea::TabbedView	多页显示模式,类似tabView

1、实现工具

在这里插入图片描述
在这里插入图片描述

(1)创建项目,基于QMainWindow

(2)添加资源文件,设置界面

在这里插入图片描述

(3)添加UI与类

在这里插入图片描述
在这里插入图片描述

(4)实现功能

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "formdoc.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    setCentralWidget(ui->mdiArea);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_actDocNew_triggered()
{
    FormDoc *formDoc = new FormDoc(this);
    // formDoc->setAttribute(Qt::WA_DeleteOnClose); 不需要,框架会自动回收
    ui->mdiArea->addSubWindow(formDoc);
    formDoc->show();

    ui->actCopy->setEnabled(true);
    ui->actCut->setEnabled(true);
    ui->actPaste->setEnabled(true);
    ui->actFont->setEnabled(true);
}

#include <QMdiSubWindow>
#include <QFileDialog>
void MainWindow::on_actDocOpen_triggered()
{
    bool needNew = false;
    FormDoc *formDoc = nullptr;

    if(ui->mdiArea->subWindowList().count() > 0)
    {
        formDoc = (FormDoc*)ui->mdiArea->activeSubWindow()->widget();
        needNew = formDoc->isFileOpenedDoc();
    }
    else
    {
        needNew = true;
    }

    if(needNew)
    {
        formDoc = new FormDoc(this);
        ui->mdiArea->addSubWindow(formDoc);
    }

    QString strFileName = QFileDialog::getOpenFileName(this, "打开文档", "",
                          "文本文件(*.txt);;所有文件(*.*)");
    formDoc->loadFromFile(strFileName);
    formDoc->show();

    ui->actCopy->setEnabled(true);
    ui->actCut->setEnabled(true);
    ui->actPaste->setEnabled(true);
    ui->actFont->setEnabled(true);

}

void MainWindow::on_actCloseAll_triggered()
{
    ui->mdiArea->closeAllSubWindows();

    ui->actCopy->setEnabled(false);
    ui->actCut->setEnabled(false);
    ui->actPaste->setEnabled(false);
    ui->actFont->setEnabled(false);
}

void MainWindow::on_actFont_triggered()
{
    FormDoc *formDoc = (FormDoc*)ui->mdiArea->activeSubWindow()->widget();
    formDoc->setTextFont();
}

void MainWindow::on_actCut_triggered()
{
    FormDoc *formDoc = (FormDoc*)ui->mdiArea->activeSubWindow()->widget();
    formDoc->textCut();
}

void MainWindow::on_actCopy_triggered()
{
    FormDoc *formDoc = (FormDoc*)ui->mdiArea->activeSubWindow()->widget();
    formDoc->textCopy();
}

void MainWindow::on_actPaste_triggered()
{
    FormDoc *formDoc = (FormDoc*)ui->mdiArea->activeSubWindow()->widget();
    formDoc->textPaste();
}

void MainWindow::on_actMdiMode_triggered(bool checked)
{
    if(checked)
    {
        ui->mdiArea->setViewMode(QMdiArea::TabbedView);
        ui->mdiArea->setTabsClosable(true); //可关闭
        ui->actCascade->setEnabled(false);
        ui->actTile->setEnabled(false);
    }
    else
    {
        ui->mdiArea->setViewMode(QMdiArea::SubWindowView);
        ui->actCascade->setEnabled(true);
        ui->actTile->setEnabled(true);
    }
}

void MainWindow::on_actCascade_triggered()
{
    ui->mdiArea->cascadeSubWindows();
}

void MainWindow::on_actTile_triggered()
{
    ui->mdiArea->tileSubWindows();
}

void MainWindow::on_mdiArea_subWindowActivated(QMdiSubWindow *arg1)
{
    Q_UNUSED(arg1)

    // 将选项变化,显示在状态栏
    if(ui->mdiArea->subWindowList().count() == 0)
    {
        ui->actCopy->setEnabled(false);
        ui->actCut->setEnabled(false);
        ui->actPaste->setEnabled(false);
        ui->actFont->setEnabled(false);
        ui->statusBar->clearMessage();
    }
    else
    {
        FormDoc *formDoc = (FormDoc*)ui->mdiArea->activeSubWindow()->widget();
        ui->statusBar->showMessage(formDoc->getCurFileName());
    }
}

五、Splash与登录窗口

Qt有一个QSplashScreen类可以实现Splash窗口的功能,它提供了载入图片,自动设置窗口无边框效果功能。可以在加载界面使用。
	(QMouseEvent *)event->globalPos()	获取鼠标的位置,即鼠偏离屏幕左上角的位置
	pos()	获取主窗口(Widget窗口)左上角(边框的左上角,外左上角)相对于屏幕左上角的偏移位置。

1、实现工具

(1)拷贝上一个项目

(2)添加UI,选择Dialog

在这里插入图片描述
在这里插入图片描述

(3)添加登录验证

#include "mainwindow.h"
#include <QApplication>
#include "dialoglogin.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    DialogLogin *dlg = new DialogLogin();

    if(dlg->exec() == QDialog::Accepted)
    {
        MainWindow w;
        w.show();
        return a.exec();
    }

    return 0;
}

(4)鼠标和窗口位置计算方法

在这里插入图片描述
使用向量原理,可以得到:使用鼠标的向量减去相对向量(鼠标相对窗口的向量),可以得出目标窗口的向量。

void DialogLogin::mousePressEvent(QMouseEvent *event)
{
    //左击
    if(event->button()  == Qt::LeftButton)
    {
        m_moveing = true;
        m_lastPos = event->globalPos() - pos();
    }

    return QDialog::mousePressEvent(event);
}

void DialogLogin::mouseMoveEvent(QMouseEvent *event)
{
    //移动
    if(m_moveing && (event->buttons() && Qt::LeftButton))
    {
        move(event->globalPos() - m_lastPos);
        m_lastPos = event->globalPos() - pos();
    }

    return QDialog::mouseMoveEvent(event);
}

void DialogLogin::mouseReleaseEvent(QMouseEvent *event)
{
    //松开
    Q_UNUSED(event)
    m_moveing = false;
    //    return QDialog::mouseReleaseEvent(event);
}

(5)实现功能

#include "dialoglogin.h"
#include "ui_dialoglogin.h"

DialogLogin::DialogLogin(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::DialogLogin)
{
    ui->setupUi(this);
    setAttribute(Qt::WA_DeleteOnClose);
    setWindowFlag(Qt::SplashScreen); //关闭边框
    setFixedSize(this->width(), this->height());    // 禁止拖动窗口大小
    readSettings();
}

DialogLogin::~DialogLogin()
{
    delete ui;
}

void DialogLogin::mousePressEvent(QMouseEvent *event)
{
    //左击
    if(event->button()  == Qt::LeftButton)
    {
        m_moveing = true;
        m_lastPos = event->globalPos() - pos();
    }

    return QDialog::mousePressEvent(event);
}

void DialogLogin::mouseMoveEvent(QMouseEvent *event)
{
    //移动
    if(m_moveing && (event->buttons() && Qt::LeftButton))
    {
        move(event->globalPos() - m_lastPos);
        m_lastPos = event->globalPos() - pos();
    }

    return QDialog::mouseMoveEvent(event);
}

void DialogLogin::mouseReleaseEvent(QMouseEvent *event)
{
    //松开
    Q_UNUSED(event)
    m_moveing = false;
    //    return QDialog::mouseReleaseEvent(event);
}

#include <QSettings>
void DialogLogin::writeSettings()
{
    // 写入注册表
    QSettings settings("公司-liutt", "应用名称-text");
    settings.setValue("UserName", m_user);
    settings.setValue("Passwd", m_passwd);
    settings.setValue("saved", ui->checkBoxSave->isChecked());
}

void DialogLogin::readSettings()
{
    // 读取注册表
    QSettings settings("公司-liutt", "应用名称-text");
    bool saved = settings.value("saved", false).toBool(); //默认值
    m_user = settings.value("UserName", "user").toString(); //默认值
    QString defaultPasswd = encrypt("123456"); //加密
    m_passwd = settings.value("Passwd", defaultPasswd).toString(); //默认值

    if(saved)
    {
        ui->checkBoxSave->setChecked(true);
        ui->lineEditUser->setText(m_user);
    }
}

#include <QCryptographicHash>
QString DialogLogin::encrypt(const QString &str)
{
    QByteArray btArray;
    btArray.append(str);
    QCryptographicHash hash(QCryptographicHash::Md5);
    hash.addData(btArray);
    QByteArray btResult = hash.result();
    QString md5 = btResult.toHex();
    return md5;
}

#include <QMessageBox>
void DialogLogin::on_btnOk_clicked()
{
    QString strUser = ui->lineEditUser->text().trimmed();
    QString strPasswd = ui->lineEditPasswd->text().trimmed();

    if(strUser == m_user && encrypt(strPasswd) == m_passwd)
    {
        writeSettings();
        accept();
    }
    else
    {
        m_tryCount++;

        if(m_tryCount > 3)
        {
            QMessageBox::critical(this, "error", "错误次数太多,强制退出");
            reject();
        }

        QMessageBox::warning(this, "error", "账号不存在或密码错误");


    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1399624.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《JVM由浅入深学习九】 2024-01-15》JVM由简入深学习提升分(生产项目内存飙升分析)

目录 开头语内存飙升问题分析与案例问题背景&#xff1a;我华为云的一个服务器运行我的一个项目“csdn-automatic-triplet-0.0.1-SNAPSHOT.jar”&#xff0c;由于只是用来测试的服务器&#xff0c;只有2G&#xff0c;所以分配给堆的内存1024M查询内存使用&#xff08;top指令&a…

Self-RAG:通过自我反思学习检索、生成和批判

论文地址&#xff1a;https://arxiv.org/abs/2310.11511 项目主页&#xff1a;https://selfrag.github.io/ Self-RAG学习检索、生成和批评&#xff0c;以提高 LM 的输出质量和真实性&#xff0c;在六项任务上优于 ChatGPT 和检索增强的 LLama2 Chat。 问题&#xff1a;万能L…

活性白土数据研究:预计2029年将达到9.2亿美元

活性白土是用粘土(主要是膨润土)为原料&#xff0c;经无机酸化或盐或其他方法处理&#xff0c;再经水漂洗、干燥制成的吸附剂&#xff0c;外观为乳白色粉末&#xff0c;无臭&#xff0c;无味&#xff0c;无毒&#xff0c;吸附性能很强&#xff0c;能吸附有色物质、有机物质。广…

一键完成,批量转换HTML为PDF格式的方法,提升办公效率

在当今数字化的时代&#xff0c;HTML和PDF已经成为两种最常用的文件格式。HTML用于网页内容的展示&#xff0c;而PDF则以其高度的可读性和不依赖于平台的特性&#xff0c;成为文档分享和传播的首选格式。然而&#xff0c;在办公环境中&#xff0c;我们经常需要在这两种格式之间…

CSS注释

CSS注释 哇&#xff0c;最近我发现CSS里面的注释真是个好东西呢&#xff01;虽然它们不会在网页上显示出来&#xff0c;但是对于我这样的新手来说&#xff0c;真的很有助于理解代码是怎么工作的。 CSS注释的小秘密 你知道吗&#xff0c;CSS里的注释就像是小纸条&#xff0c;…

Leetcoder Day10|栈与队列part02(栈的应用)

语言&#xff1a;Java/C 目录 20. 有效的括号 1047. 删除字符串中的所有相邻重复项 150. 逆波兰表达式求值 今日总结 20. 有效的括号 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串&#xff0c;判断字符串是否有效。 有效字…

Android双击图片放大移动图中双击点到ImageView区域中心,Kotlin

Android双击图片放大移动图中双击点到ImageView区域中心&#xff0c;Kotlin 初始化状态&#xff0c;ImageView里面只是显示一张fitcenter被缩放的原图&#xff0c;当手指在图片上双击后&#xff08;记录双击点位置&#xff1a;mCurX&#xff0c;mCurY&#xff09;画一个红色小圆…

TensorRT模型优化部署 (八)--模型剪枝Pruning

系列文章目录 第一章 TensorRT优化部署&#xff08;一&#xff09;–TensorRT和ONNX基础 第二章 TensorRT优化部署&#xff08;二&#xff09;–剖析ONNX架构 第三章 TensorRT优化部署&#xff08;三&#xff09;–ONNX注册算子 第四章 TensorRT模型优化部署&#xff08;四&am…

AxiosError: Request failed with status code 503

spring.application.name属性指定了应用程序的名称为ssm_serviceA。这个属性用于标识应用程序&#xff0c;可以在日志、监控和其他相关功能中使用。通常情况下&#xff0c;应用程序的名称是用来区分不同的应用程序或服务的。 通过配置spring.application.name&#xff0c;你可以…

LSTM学习笔记

上一篇文章中我们提到&#xff0c;CRNN模型中用于预测特征序列上下文的模块为双向LSTM模块&#xff0c;本篇中就来针对该模块的结构和实现做一些理解。 Bidirectional LSTM模块结构如下图所示&#xff1a; 在Pytorch中&#xff0c;已经集成了LSTM模块&#xff0c;定义如下&…

Sqoop故障排除指南:处理错误和问题

故障排除是每位数据工程师和分析师在使用Sqoop进行数据传输时都可能遇到的关键任务。Sqoop是一个功能强大的工具&#xff0c;但在实际使用中可能会出现各种错误和问题。本文将提供一个详尽的Sqoop故障排除指南&#xff0c;涵盖常见错误、问题和解决方法&#xff0c;并提供丰富的…

认识并使用Shiro技术

认识并使用Shiro 一、对Shiro的基本认知1、Shiro是什么&#xff1f;2、Shiro的核心组件是&#xff1f;2.1 Subject2.2 UsernamePasswordToken2.3 Realm&#xff08;重点是&#xff1a;AuthorizingRealm用于授权、AuthenticatingRealm用于认证&#xff09;2.4 SecurityManager2.…

NLP论文阅读记录 - 2021 | WOS 基于多头自注意力机制和指针网络的文本摘要

文章目录 前言0、论文摘要一、Introduction1.1目标问题1.2相关的尝试1.3本文贡献 二.问题定义和解决问题的假设问题定义解决问题的假设 三.本文方法3.1 总结为两阶段学习3.1.1 基础系统 3.2 重构文本摘要 四 实验效果4.1数据集4.2 对比模型4.3实施细节4.4评估指标4.5 实验结果4…

面试官:什么是泛型擦除、泛型上界、泛型下界、PECS原则?

尼恩说在前面 在40岁老架构师 尼恩的读者交流群(50)中&#xff0c;最近有小伙伴拿到了一线互联网企业如阿里、滴滴、极兔、有赞、希音、百度、网易、美团的面试资格&#xff0c;遇到很多很重要的面试题&#xff1a; 问题1&#xff1a;什么是PECS原则&#xff1f; 说说具体怎么…

回溯法:回溯法通用模版以及模版应用

从一个问题开始 给定两个整数 n 和 k&#xff0c;返回 1 ... n 中所有可能的 k 个数的组合。 示例: 输入: n 4, k 2 输出: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4] ] 很容易想到 用两个for循环就可以解决。 如果n为100&#xff0c;k为50呢&#xff0c;那就50层for循…

文字的baseLine算法

使用canvas的drawText方法时候&#xff0c;除了要传入画笔和text还需要传入一个x坐标和y坐标。这边的x和y坐标是Baseline的坐标。 public void drawText(NonNull String text, float x, float y, NonNull Paint paint) {super.drawText(text, x, y, paint);} top:是 baseLine到…

微信小程序之WXML 模板语法之数据绑定、事件绑定、wx:if和列表渲染

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

消息中间件之Kafka(二)

1.Kafka线上常见问题 1.1 为什么要对topic下数据进行分区存储? 1.commit log文件会受到所在机器的文件系统大小的限制&#xff0c;分区之后可以将不同的分区放在不同的机器上&#xff0c; 相当于对数据做了分布式存储&#xff0c;理论上一个topic可以处理任意数量的数据2.提…

OpenHarmony 应用开发入门 (二、应用程序包结构理解及Ability的跳转,与Android的对比)

在进行应用开发前&#xff0c;对程序的目录及包结构的理解是有必要的。如果之前有过android开发经验的&#xff0c;会发现OpenHarmony的应用开发也很简单&#xff0c;有很多概念是相似的。下面对比android分析总结下鸿蒙的应用程序包结构&#xff0c;以及鸿蒙对比android的诸多…

【报错】Arco新建工程时 Error: spawnSync pnpm.cmd ENOENT

文章目录 安装环境开始安装选择技术栈选择pro项目遇到的问题 安装步骤&#xff1a;https://arco.design/vue/docs/pro/start 安装环境 npm i -g arco-cli开始安装 arco init hello-arco-pro选择技术栈 ? 请选择你希望使用的技术栈React❯ Vue选择pro项目 ? 请选择一个分类业…