一点一滴成长

导航

《QT Creator快速入门》第三章:窗口部件(2)

1、QDialog派生对话框

    除了QDialog外,Qt中还提供了一些从QDialog派生的Dialog,如:

    ①、颜色对话框QColorDialog用来显示和获取用户选择的颜色,QColor为颜色类。

    //QColorDialog::getColor显示一个模态颜色对话框并获得用户选择的颜色
    QColor clr(255/*r*/, 255/*g*/, 255/*b*/, 255/*alpha*/);
    clr = QColorDialog::getColor(Qt::red/*初始颜色*/, this/*父窗口*/, QString::fromUtf8("颜色对话框")/*标题*/,
                                        QColorDialog::ShowAlphaChannel/*显示透明度设置,可选*/);
    qDebug() << clr; //输出为:QColor(ARGB 1, 1, 0, 0)
View Code

    ②、文件对话框QFileDialog用来显示一个选择文件/文件夹、保存文件功能的对话框。

   QFileDialog::getOpenFileName显示一个文件选择模态对话框,QFileDialog::getOpenFileNames显示一个多文件选择模态对话框
    QFileDialog::getExistingDirectory显示一个目录选择模态对话框,QFileDialog::getSaveFileName显示一个保存文件对话框或文件另存为对话框
    QString str = QFileDialog::getOpenFileName(this/*父窗口*/, QString::fromUtf8("文件对话框")/*标题*/, "C:"/*初始打开目录*/,
                                               QString::fromUtf8("图片文件(*png *jpg);;文本文件(*txt)")/*文件类型,可选*/);
    qDebug() << str; //输出为"C:/condition_select_btn_normal.png"
View Code

    ③、字体对话框QFontDialog提供了一个可以选择字体的对话框。

    //QFontDialog::getFont显示一个模态字体对话框并获得用户选择的字体
    bool bOk;
    QFont font = QFontDialog::getFont(&bOk/*是否点击了ok按钮*/, this/*父窗口*/);
    if(bOk)
        ui->pushButton->setFont(font); //设置按钮字体
View Code

    ④、输入对话框QInputDialog提供了一个接收和获取用户输入的对话框,并且可以设置只接收用户输入text或int或double。QInputDialog还可以提供具有一个下拉列表供用户选择的对话框。

    QInputDialog::getText显示一个字符串输入对话框
    QInputDialog::getInt显示一个输入整型数值的对话框
    QInputDialog::getDouble显示一个输入浮点型数值的对话框
    bool bOk;
    QString str = QInputDialog::getText(this/*父窗口*/, QString::fromUtf8("输入字符串对话框")/*标题*/, QString::fromUtf8("请输入用户名")/*说明文字*/,
                                        QLineEdit::Normal/*还有Password等输入显示模式*/, "admin"/*默认文本*/, &bOk/*是否点击了确认按钮*/);
    int value = QInputDialog::getInt(this/*父窗口*/, ""/*标题*/, ""/*说明*/, 100/*默认显示*/, -1000/*最小值*/, 1000/*最大值*/,
                                     10/*使用箭头按钮,数值每次变化10*/, &bOk/*是否点击了确认按钮*/);
    QStringList items = {"item1", "item2"};
    QString item = QInputDialog::getItem(this, "", "", items, 0/*默认显示第一个条目*/, true/*条目可以修改*/, &bOk);
View Code

   

    ⑤、消息提示对话框QMessageBox提供一个模态对话框来显示信息和提示用户,使用如下:

 //问题对话框
    int ret1 = QMessageBox::question(this, "question dialog", "Do you understand Qt?", QMessageBox::Yes, QMessageBox::No);
    if(ret1 == QMessageBox::Yes)
        qDebug() << "I understand Qt.";

    //提示对话框
    int ret2 = QMessageBox::information(this, "information dialog", "this is Qt", QMessageBox::Ok);
    if(ret2 == QMessageBox::Ok)
        qDebug() << "Ok Qt.";

    //警告对话框
    int ret3 = QMessageBox::warning(this, "warning dialog", "Qt Warning!", QMessageBox::Abort);
    if(ret3 == QMessageBox::Abort)
        qDebug() << "Warning.";

    //错误对话框
    int ret4 = QMessageBox::critical(this, "error dialog", "Qt error!", QMessageBox::YesAll);
    if(ret4 == QMessageBox::YesAll)
        qDebug() << "error.";

    //关于对话框
    QMessageBox::about(this, "about dialog", "this is about dialog");
View Code

     

      如果想使用自己的图标或自定义按钮,那么可以自己创建QMessageBox对象,然后调用相关函数来进行操作:

       QMessageBox box(QMessageBox::Question, "title", "text", QMessageBox::Yes/* | QMessageBox::No*/);
       QPushButton btn("No");
       box.addButton(&btn, QMessageBox::NoRole);
       int select = box.exec();
       if(select == QMessageBox::Yes)
           qDebug() << "select Yes";
       else if(select == QDialog::Rejected)
           qDebug() << "select No";
View Code

    ⑥、进度对话框QProgressDialog提供了一个进度条来显示进度,使用如下:

void MainWindow::on_pushButton_clicked()
{
    //最小值和最大值之差指定了进度总步数,总步数越大进度从0到100%时间越长
    int minValue = 0;
    int maxValue = 100000; //十万的步数进度从0到100%大概为三四秒
    QProgressDialog* dialog = new QProgressDialog("current progress", "cancel", minValue, maxValue, this);
    dialog->setWindowTitle("ProgressDialog");
    dialog->setModal(true);
    dialog->setAutoClose(false);
    dialog->setAutoReset(false);
    dialog->show();

    for(int i=0; i< maxValue + 1; i++)
    {
        dialog->setValue(i); //移动进度到指定位置
        QApplication::processEvents();//防止用户界面冻结
        if(dialog->wasCanceled())//判断用户是否点击了取消按钮
          break;
    }
}
View Code

           

   上面的QApplication::processEvents()用来处理消息队列中的未决事件,因为整个循环操作很有可能会持续一段时间,而这时候QProgressDialog界面会无响应,所以可以调用这个方法来处理未决的消息事件。
   因为模态的QProgressDialog的setValue方法中会调用QApplication::processEvents,所以我们使用QProgressDialog的时候需要注意,比如不能在paintEvent方法中使用QProgressDialog,否则可能产生递归崩溃(paintEvent中调用setValue,setValue中产生paint event,processEvents中调用paintEvent)。
   虽然模态的QProgressDialog的setValue方法中也会调用QApplication::processEvents,但个人猜测也许是由于setValue中的QApplication::processEvents并不是必然调用或者其它原因,我们需要再次手动调用QApplication::processEvents()来防止QProgressDialog界面冻结。

    ⑦、错误信息对话框QErrorMessage可以用来显示错误信息:

void MainWindow::on_pushButton_clicked()
{
    QErrorMessage* pMsg = new QErrorMessage(this);
    pMsg->setWindowTitle(QString::fromStdWString(L"向导对话框 "));
    pMsg->showMessage(QString::fromWCharArray(L"错误信息"));
}
View Code

        

    ⑧、向导对话框QWizard提供了一个设计向导界面的框架,简单使用如下所示,Qt示例中有三个使用QWizard深成向导对话框的例子:Class Wizard、License Wizard、Trivial Wizard。

void MainWindow::on_pushButton_clicked()
{
    QWizardPage* page1 = new QWizardPage;
    page1->setTitle(QString::fromUtf8("对话框"));
    QWizardPage* page2 = new QWizardPage;
    page2->setTitle(QString::fromUtf8("用户选择信息页面"));
    QWizardPage* page3 = new QWizardPage;
    page3->setTitle(QString::fromUtf8("结束页面"));

    QWizard w(this);
    w.setWindowTitle(QString::fromStdWString(L"向导对话框 "));
    w.setTitleFormat(Qt::PlainText);
    w.addPage(page1);
    w.addPage(page2);
    w.addPage(page3);
    w.exec();
}
View Code

     

    ⑨、还有几个跟打印有关的对话框:QPageSetupDialog页面设置对话框、QPrintDialog打印对话框、QPrintPreviewDialog打印预览对话框。

2、QFrame

    QFrame边框类是带有边框部件的基类,QFrame的子类有QLabel、QLCDNumber、QStackedWidget、QToolBox和QAbstractScrollArea等。QAbstractScrollArea类是所有带有滚动条类的抽象基类,QTextEdit文本编辑器类就是QAbstractScrollArea的子类。我们可以在设计模式下对这些部件的边框属性(frameShape、frameShadow、lineWidth、midLineWidth)进行修改设置,以达到不同的边框和界面效果,如下所示:

    下面是对一个QLabel(frameShadow默认为palin),lineWidth设为1,midLineWidth设为0,frameShape进行不同的设置的效果:

     

    下面手对一个QFrame的frameShape、frameShadow、midLineWidt进行不同设置的效果:

     

    也可以在代码中使用QFrame的方法来对边框进行设置:

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //ui为设计类对象指针,frame为QFrame对象指针
    ui->frame->setFrameShape(QFrame::Box);
    ui->frame->setFrameShadow(QFrame::Sunken);
    ui->frame->setLineWidth(5);
    ui->frame->setMidLineWidth(1);
}
View Code

3、QLabel

    QLabel可以用来显示文本或图片。可以设置其alignment属性修改显示方式,如水平选择AlignHCenter,垂直选择AlignVCenter,这样就能在正中间显示。

    显示图片的方法为先添加头文件<QPixmap>,然后添加以下代码:

MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyWidget)
{
    ui->setupUi(this);
    ui->label_2->setPixmap(QPixmap("F:/logo.png"));
}
View Code

    显示gif动态图片的方法为先添加头文件<QMovie>,然后添加以下代码:

MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyWidget)
{
    ui->setupUi(this);
    QMovie* movie = new QMovie("F:/logo.gif");
    ui->label_2->setMovie(movie);
    movie->start();
}
View Code

4、QLCDNumber

    QLCDNumber部件可以显示类似LCD液晶屏一样效果的数字或特定字母,通过修改部件属性来设置该部件:smallDecimalPoint设置显示小数点,digitCount设置显示数字个数,mode设置十进制(Dec)、十六进制(Hex)、二进制(Bin)等显示,segmentStyle设置数码显示样式,value设置要显示的数值,也可以通过方法display()来设置显示的数值。它可以显示部分与数值相关的字符如A、B、C、D、E、F、g,还可以显示度符号(输入时使用单引号来替代)。效果如下所示:

     

5、QStackedWidget

 QStackedWidget是一个能提供具有多个Widget界面的部件,但当前显示的只有一个Widget界面,可以设置当前显示哪一个Widget界面。在界面设计下可以通过QStackedWidget控件右上角的箭头来选择当前显示的页面,也可以在代码中通过setCurrentIndex方法来设置。

 我们可以在当前窗口的QStackedWidget部件下放置一个button,然后点击右上角的箭头切换到另一个页面再放置一个Label,然后在这个窗口下添加一个QListWidget,通过list的选择来设置当前QStackedWidget页面的显示,方法是在设计模式下进入信号/槽编辑模式,拖动QListWidget到QStackedWidget,将QListWidget的currentRowChanged信号和QStackedWidget的setCurrentIndex槽关联起来,代码实现关联的话就是使用connect方法:QObject::connect(listWidget, SIGNAL(currentRowChanged(int)), stackedWidget, SLOT(setCurrentIndex(int)))。

 

6、QToolBox

QToolBox是一个可以显示一列层叠窗口部件,就像QQ联系人列表一样的多个列表展示界面,只有一个列表可以被当前展开。我们在设计模式下将一个QToolBox放到当前窗口下(frameShape选择Box),可以看到默认有两个窗口页面,当前页面为Page1,点击Page2后当前页面为Page2,通过currentItemText属性来设置当前页面的标题名,我们将他俩改成“好友”、“陌生人”之后再右击QToolBox选择插入页,再设置其名称为“黑名单”,再运行程序就会看到以下显示效果:

 

7、Button

    QAbstractButton是按钮部件的抽象基类,QPushButton、QRadioButton、QCheckBox等Button部件都是从其派生而来的。

    ①、QPushButton

     

       如图,Button1是一个普通的QPushButton。们可以右键按钮->转到槽->选择clicked()信号 来添加信号/槽。

               Button2是在设计模式下将其checked属性设置,这样点击Button就会有选中和取消的效果。我们可以右键按钮->转到槽->选择clicked(bool)信号 来添加信号/槽,其中bool表示是否checked。

               Button3是在设计模式下将其flat属性设置,使其没有了边框。

               Button4是一个设置了图标的QPushButton,实现方法见下。

               Button5是一个附加下拉菜单的按钮,类似comboBox控件,实现方法见下方:

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

    ui->pushBtn4->setIcon(QIcon("F:/img.png"));

    QMenu* menu = new QMenu(this);
    menu->addAction(QIcon("F:/log.png"), "item1");
    menu->addAction(QIcon("F:/log.png"), "item2");
    ui->pushBtn5->setMenu(menu);
}
View Code

               QToolButton也可以实现带一个下拉菜单的效果:

    QMenu* menu = new QMenu(this);
    menu->addAction("item1");
    menu->addAction("item2");
    ui->toolButton->setMenu(menu);
    ui->toolButton->setPopupMode(QToolButton::MenuButtonPopup);
View Code

             

    ②、QCheckBox和QRadioButton

       复选按钮QCheckBox和单选按钮QRadioButton一般是放到QGroupBox中来使用,如下图所示:

    

       对于QCheckBox我们可以在设计模式下右击->转到槽->选择stateChanged(int)信号来 定义信号/槽,其参数int可以表示选择状态。

       对于QRadioButton我们可以在设计模式下右击->转到槽->选择clicked(bool)信号来 定义信号/槽,其参数bool可以表示是否选中。

      在代码中我们可以使用QButtonGroup类来管理QCheckBox、QRadioButton按钮:

    QButtonGroup group;
    group.addButton(ui->radioButton);
    ui->radioButton_2->setChecked(true);
    group.addButton(ui->radioButton_2);
    group.setExclusive(true);

    auto pBtn = group.checkedButton();
    assert(pBtn == ui->radioButton_2);

8、QLineEdit

    QLineEdit是一个单行编辑器,它还自动提供了剪切、复制、黏贴、撤销的功能。

    ①、可以在设计模式下修改QLineEdit的echoMode属性,其中Normal为正常输入,NoEcho为不显示输入,Password为密码输入样式,PasswordEchoOnEidt为在编辑时显示正常字符,其它情况下为密码样式。

    ②、可以通过设置inputMask(输入掩码)属性来限制输入的内容,掩码含义如下,比如设置成A为只能输入A-Z,a-z,X为只能输入0-9,>AA-!\A表示应该输入4个字符,第三个字符为'-',字符'-'之前的应该为大写,前两个字符应该为字母,第四个字符为'A':

    ③、可以通过QValidator验证器来进一步限制QLineEdit的输入,比如限制输入100-999之间的数字使用QIntValidator,如下示例,限制输入浮点型数值的话使用QDoubleValidator验证器。

MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyWidget)
{
    ui->setupUi(this);
    QValidator* validator = new QIntValidator(100, 999, this);
    ui->lineEdit->setValidator(validator);
}
View Code

           如果想要设置一般的字符约束,就要使用QRegexpValidator正则表达式验证器了,如以下实现了在开头输入'-'或者不输入,然后再可以输入最多三个数字:

MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyWidget)
{
    ui->setupUi(this);
    
    QRegExp rx("-?\\d{1,3}");
    QValidator* validator = new QRegExpValidator(rx, this);
    ui->lineEdit->setValidator(validator);
}
View Code

    ④、还可以通过QCompleter实现自动补全功能:

    QCompleter* com = new QCompleter({"qt", "qt_list", "qtTest", this);
    com->setCaseSensitivity(Qt::CaseInsensitive); //设置大小写不敏感
    ui->lineEdit->setCompleter(com);
View Code

   

    ⑤、在设计模式下右击QLineEdit->转到槽->可以看到有textChanged()、returnPressed()等信号,可以对其实现槽函数。

 9、数值设定框

QTimeEdit、QDateEdit、QDateTimeEdit提供了对时间和日期的修改,QSpinBox和QDoubleSpinBox分别可以用来设置整数和浮点数,如下图所示:

将QTimeEdit属性dispalyFormat设置为hh:mm:ss.zzz表示00:00:00.000(24小时),h:m:sA表示0:0:0(12小时)。设置QDateEdit的calendarPopup属性就可以使用弹出的日历部件来设置日期。也可以使用代码来设置QDateTimeEdit:
ui->dateTimeEdit->setDateTime(QDateTime::currentDateTime());
    ui->dateTimeEdit->setDisplayFormat(QString::fromStdWString(L"yyyy年mm月dd日 ddd hh时mm分ss秒"));

   在设计模式下还可以对QSpinBox、QDoubleSpinBox的一些属性进行设置,比如suffix后缀属性可以设置成%可以用于显示百分数,prefx前缀属性设置成¥可以用来表示人民币,还可以设置其最大值maximum、最小值minimum、单步值singleStep、小数位数decimals等。

    

10、Slider滑块部件

    QAbstractSlider是一个虚基类,QScrollBar滚动条、QSlider进度控制、QDial刻度表盘等部件都是从它派生的。

    设计模式下QDial的notchesVisible属性用来设置是否显示刻度,notchTarget属性用来设置刻度之间的间隔,wrapping属性用来设置是否首尾相连。

    设计模式下QScrollBar的minimum和maximum属性分别用来设置最小和最大值,singleStep属性是按下←和→方向键后的增加或减少值,pageStep属性是按下↑或↓方向键后增加或减少的值,value和sliderPosition属性是当前值,tracking属性设置是否跟踪(就是在拖动滑块时,每移动一个刻度就会发射valueChanged()信号,如果不设置的话只有拖动滑块释放时才发射该信号),orientation属性设置部件是水平还是垂直方向,invertedAppearance属性用来设置滑块所在的位置,invertedControls属性用来设置反向控制。

    设计模式下QSlider的tickPosition属性用来设置是否显示刻度及刻度位置,tickInterval属性用来设置刻度间隔。

    我们在设计模式下加入一个Dial部件、一个Vertical Scroll Bar部件,一个Horizontal Slider部件。设置Dial的notchesVisible属性,使其显示刻度。然后进入编辑信号/槽模式,将Dial的sliderMoved(int)信号分别与其它两个部件的setValue(int)槽相关联, 然后运行程序可以看到当拖动Dial的滑块的时候,其它四个部件也随之滑动,如下图所示:

    

 11、ProgressBar进度条

  QProgressBar是进度条类,其成员函数setRange用来设置进度范围,setValue()用来设置当前进度,setFormat()用来设置进度条上文字,setOrientation()用来设置水平或垂直方向。

  

  12、QMdiArea 部件提供一个可以显示MDI多文档界面的区域,用来有效的管理多个窗口。QMdiArea中的子窗口是QMdiSubWindow类型,它包含一个标题栏和中心区域,可以向它的中心区域添加部件。如下代码是在按钮点击事件方法中向一个QMdiArea添加子窗口,子窗口上是一个编辑器:

      

void MainWindow::on_pushButton_clicked()
{
    QTextEdit* edit = new QTextEdit;
    
    QMdiSubWindow* child = ui->mdiArea->addSubWindow(edit);
    child->setWindowTitle("child window");
    child->show();
}

     

 13、QDockWidget 部件可以停靠在窗口中,也可以悬浮起来作为桌面顶级窗口,类似工具栏,它也包含一个标题栏和内容区域,float属性设置可以在窗口内悬浮,features属性设置是否可以关闭、移动、悬浮等,allowedArea属性设置可以停靠的区域。如下是一个包含QPushButton和QFontComboBox的Dock部件,它可以在窗口外悬浮或者在窗口内停靠:

        

posted on 2020-08-21 13:23  整鬼专家  阅读(808)  评论(0编辑  收藏  举报