1. 程式人生 > >Qt基本控件及三大布局

Qt基本控件及三大布局

com em1 button extc sets 鼠標滑過 可視化 狀態欄 int

Qt基本控件及三大布局

來源: http://blog.csdn.net/a2604539133/article/details/73920696

Qt基本模塊

技術分享

一、Qt的三大布局

  1. QHBoxLayout:
    1. 水平顯示布局,所有在其上面擺放的控件只能水平排列下去;
  2. QVBoxLayout:
    1. 垂直顯示布局,所有在其上面擺放的控件只能垂直排列下去;
  3. QGridLayout
    1. 格子顯示布局,可以按照表格的形式顯示布局;

二、Qt的控件

  1. label:標簽,可以顯示文本信息,只讀;
  2. pushbutton : 普通按鈕;
  3. radiobutton : 單選按鈕,多個單選按鈕中只能選擇一個,但是必須放入groupbox中,類似單選題;
  4. checkbox : 多選復選按鈕,可以選擇同時選擇多個,類似多選題;
  5. lineedit : 單行文本編輯框,可以輸入單行文本;
  6. textedit : 多行文本輸入框,可以輸入顯示多行文本和圖片;
  7. combobox : 下拉文本輸入框,在輸入框的最右邊有個三角下拉按鈕,可以選擇輸入,也可以手動輸入;
  8. textbrower : 多行文本顯示框,只讀;
  9. groupbox : 可以在裏面放入特點的東西,統一管理;
  10. slider : 模擬顯示滑動條;
  11. spinbox : 數值顯示滑動條;
  12. dateedit :
  13. timeedit :
  14. datetimeedit :
  15. lcdnumber :

三、Qt的信號槽

  1. 在Qt中所有的對象(繼承QObject類)都有connect函數,只要有這個函數就能建立信號槽(通過觸發某個控件的信號函數,執行槽中相應的函數);(暫時這樣理解,還是有點理解不全面的,之後學習到再來修改);
  2. 在Qt中信號槽中可以使用自帶的函數,四個參數;也可以執行自定義的函數,三個參數;具體看下面test4的例子就明白了。
#include <QtWidgets/QApplication>
#include <QtCore/qdebug.h>
#include <QtWidgets/qcompleter.h>
#include <QtWidgets/qlineedit.h>
#include <QtWidgets/qlabel.h>
#include <QtWidgets/qcombobox.h>
#include <QtWidgets/qcheckbox.h>
#include <QtWidgets/qradiobutton.h>
#include <QtWidgets/qtextedit.h>
#include <QtWidgets/qtextbrowser.h>
#include <QtWidgets/qgroupbox.h>
#include <QtWidgets/qslider.h>
#include <QtWidgets/qspinbox.h>
#include <QtWidgets/qdatetimeedit.h>
#include <QtWidgets/qtabwidget.h>
#include <QtWidgets/qlcdnumber.h>
#include <QtGui/qpixmap.h>
#include <QtCore/qobject.h>
#include <QtWidgets/qboxlayout.h>
#include <QtWidgets/qpushbutton.h>
#include "MyWidgetEvent.h"


void test() ;


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

    QApplication a(argc, argv);

    test() ;

    return a.exec();
}


void test(){


}


void test5ManyKongJian() {

    QWidget *nanWidget = new QWidget() ;
    QVBoxLayout *nanVLayout = new QVBoxLayout() ;

    /*
    **測試label控件
    */
    QLabel *label=nullptr ;
    nanVLayout->addWidget( label = new QLabel("<a href=www.baidu.com>baidu</a>") ) ;
    //QPixmap me("./me.png") ;
    //label->setPixmap( me ) ;//問題:鏈接和圖片重復了,怎麽分開
    label->setWordWrap( true ) ;
    label->adjustSize() ;
    nanVLayout->connect( label , &QLabel::linkActivated , []( QString str){
        qDebug()<<str ;
    } ) ;
    /*
    **測試lineedit控件
    */
    QLineEdit *lineEdit ;
    nanVLayout->addWidget( lineEdit = new QLineEdit("hello") ) ;
    /*
    **測試button控件
    */
    QPushButton *button ;
    nanVLayout->addWidget( button = new QPushButton("???") ) ;
    button->setStyleSheet("QPushButton {font:bold 16px; color:red;padding:5px}") ;
    nanWidget->connect( button , &QPushButton::clicked , [](bool flag){
        qDebug()<< "button" ;
    }) ;
    /*
    **測試radiobutton控件
    */
    QRadioButton *radioButton ;
    nanVLayout->addWidget( radioButton = new QRadioButton("qradiobutton") ) ;
    radioButton->setStyleSheet("QRadioButton {font:bold  16px;color:blue;padding:5px}") ;
    radioButton->connect( radioButton , &QRadioButton::clicked , [](bool flag){
        qDebug()<< flag ;
    }) ;
    /*
    **測試ckeckbox控件
    */
    QCheckBox *check ;
    nanVLayout->addWidget( check = new QCheckBox("chekcbox") ) ;
    /*
    **測試combobox控件
    */
    QComboBox *combobox ;
    nanVLayout->addWidget( combobox = new QComboBox() ) ;
    combobox->addItem("select item1") ;
    combobox->addItem("select item2") ;
    combobox->addItem("...  ...") ;
    combobox->setEditable(true) ;
    lineEdit->setText("start") ;
    combobox->connect( combobox , SIGNAL(activated(const QString &)) , lineEdit , SLOT(setText(const QString &)) ) ;//這裏的下標要跟著顯示
    combobox->setCompleter( new QCompleter(combobox->model()) ) ;
    /*
    **測試textedit
    */
    QTextEdit *textEdit ;
    nanVLayout->addWidget( textEdit = new QTextEdit("textedit") ) ;
    textEdit->setText("<table border=2> "
                    "<tr><td>good</td><td>good</td><td>good</td></tr>"
                    "<tr><td>nice</td><td>nice</td><td>nice</td></tr>"
                    "</table>"
                    "<img src=./me.png></img>") ;
    textEdit->connect( textEdit , &QTextEdit::textChanged,[&](){
        //問題:textEdit->toPlainText() ;怎麽才能獲取到textEdit的實體,this->sender()
        //QTextEdit _edit = (QTextEdit *)QObject::sender();
        qDebug()<<textEdit->toPlainText() ;
    }) ;
    textEdit->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded) ;
    textEdit->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn) ;
    /*
    **測試groupbox控件
    */
    QGroupBox *groupBox ;
    nanVLayout->addWidget( groupBox = new QGroupBox("groupbox") ) ;
    QHBoxLayout *hLayout ;
    groupBox->setLayout( hLayout = new QHBoxLayout() ) ;
    hLayout->addWidget( new QRadioButton("boy") ) ;
    hLayout->addWidget( new QRadioButton("girl") ) ;
    /*
    **測試模擬顯示條slider
    */
    QSlider *slider ;
    nanVLayout->addWidget( slider = new QSlider() ) ;
    slider->setMinimum( -100 ) ;
    slider->setMaximum( 100 ) ;
    /*
    **測試數字顯示條
    */
    QSpinBox *spinBox ;
    nanVLayout->addWidget( spinBox = new QSpinBox() ) ;
    spinBox->setMinimum( -100 ) ;
    spinBox->setMaximum( 100 ) ;
    slider->connect( slider , SIGNAL(valueChanged(int)) , spinBox , SLOT(setValue(int)) ) ;
    spinBox->connect( spinBox , SIGNAL(valueChanged(int)) , slider , SLOT(setValue(int)) ) ;
    /*
    **測試時間設置
    */
    nanVLayout->addWidget( new QDateTimeEdit() ) ;
    /*
    **測試顯示時間,只讀
    */
    QLCDNumber *number ;
    nanVLayout->addWidget( number = new QLCDNumber() ) ;
    number->display("1314") ;
    number->setMode(QLCDNumber::Hex) ;
    number->setSegmentStyle(QLCDNumber::Filled) ;

    nanWidget->setLayout( nanVLayout ) ;
    nanWidget->setWindowTitle("control") ;
    nanWidget->show() ;
}


void test4GridAndHBox() {

    QWidget *nanWidget = new QWidget() ;
    QGridLayout *nanGridLayout = new QGridLayout() ;
    QHBoxLayout *nanHBoxLayout = new QHBoxLayout() ;

    nanGridLayout->addWidget( new QLabel("Username") , 1 , 1 ) ;
    nanGridLayout->addWidget( new QLineEdit() , 1 , 2 ) ;
    nanGridLayout->addWidget( new QLabel("Username") , 2 , 1 ) ;
    nanGridLayout->addWidget( new QLineEdit() , 2 , 2 ) ;
    nanGridLayout->addLayout( nanHBoxLayout , 3 , 2 ) ;

    nanHBoxLayout->addStretch(1) ;
    nanHBoxLayout->addWidget( new QPushButton("Login") , 1 ) ;

    nanWidget->setLayout( nanGridLayout ) ;
    nanWidget->show() ;
}


void test3GridLayout() {

    QWidget *nanWidget = new QWidget() ;
    QGridLayout *nanLayout = new QGridLayout() ;
    QPushButton *nanButton = new QPushButton() ;
    QLineEdit *nanLineEdit = new QLineEdit() ;

    nanLayout->addWidget( nanLineEdit , 1 , 1 , 1 , 2 ) ;
    nanLayout->addWidget( new QPushButton , 1, 3 ) ;
    nanLayout->addWidget( new QLineEdit , 2, 1 , 2 , 1  ) ; 
    nanLayout->addWidget( new QPushButton , 2, 2 ) ;
    nanLayout->addWidget( new QPushButton , 2, 3 ) ;
    nanLayout->addWidget( nanButton , 3 , 3 ) ;
    nanLayout->setColumnStretch( 1 , 1 ) ;
    nanLayout->setColumnStretch( 2 , 1 ) ;/*設置每列的比重*/
    nanLayout->setColumnStretch( 3 , 1 ) ;

    nanWidget->setLayout( nanLayout ) ;
    nanWidget->show() ;
}


void test2HBoxLayout() {

    QWidget *nanQWidget = new QWidget() ;

    QLineEdit *nanQLineEdit = new QLineEdit() ;

    QHBoxLayout *nanHLayout = new QHBoxLayout() ;
    nanHLayout->addWidget( nanQLineEdit , 1 ) ;
    //添加,兩個控件之間的距離addspaceing,兩個控件在layout中的比重addstretch

    nanQWidget->setLayout( nanHLayout ) ;
    nanQWidget->show() ;
} 


void test1(){

    QWidget *w  = new QWidget ;
    QVBoxLayout *vLayout = new QVBoxLayout( ) ;
    QPushButton *nanButton ;
    QLineEdit *nanLineEdit ;
    QLabel *nanLabel ;
    QString content("null") ;
    QCompleter nanQCompleter( QStringList()<<"nich"<<"chen"<<"good") ;

    vLayout->addWidget( nanLineEdit = new QLineEdit()  ) ;
    vLayout->addWidget( nanButton = new QPushButton("right") ) ;
    nanQCompleter.setFilterMode( Qt::MatchFlag::MatchContains ) ;
    nanLineEdit->setCompleter( &nanQCompleter ) ;
    nanLineEdit->setPlaceholderText( "Please input your name" ) ;
    vLayout->addWidget(  nanLabel = new QLabel() ) ;
    nanLabel->setText( content ) ;
    w->connect( nanButton , &QPushButton::clicked , [&](){
        nanLabel->setText( nanLineEdit->text() ) ;
    } ) ;

    w->setLayout( vLayout) ;
    w->show() ;
}

一、dialog、widget、mainwindow的區別

1)、dialog有exec函數,如果是dialog窗口,後邊的窗口時不可選的;
2)、widget和dialog都有show函數,如果通過這個函數顯示這兩種類型的窗口,則兩個窗口都是可選的;
3)、widget主要是在上面放置布局和控件;
4)、mainwindow可以顯示菜單,工具欄,狀態欄、托盤等功能。

二、dialog窗口

這個dialog窗口只是為了給人們提供更好的可視化操作,但是對於程序員而言,這個操作並不是立刻執行的;而是當在窗口選擇關閉後,才將選擇的結果返回給後臺,後臺才可以根據選擇的結果進行相應的操作。

#include "mydialog.h"


mydialog::mydialog(QDialog *parent):QDialog(parent) { 

    QPushButton *button = new QPushButton( "button" , this ) ;
    connect( button , SIGNAL(clicked()) , this , SLOT(slotButtonClick()) ) ;
}


void mydialog::slotButtonClick() {

#if 0
    /*dialog和widget的區別,exec和show的區別而已*/
    QDialog *dlg = new QDialog ;
    QPushButton *button = new QPushButton("close" , dlg ) ;
    connect( button , SIGNAL(clicked()) , dlg , SLOT(reject()) ) ;
    int ret = dlg->exec( ) ;
    //通過exec顯示出來的窗口稱為,模塊對話框
    // 在模塊對話框中,exec有自己的消息循環,並且把app的消息循環接管了
    // 如果Dialog是通過exec來顯示,那麽可以通過accept或者reject來關閉窗口
    // 如果Dialog是通過show來顯示,那麽可以通過close來關閉窗口,這個和QWidget一樣的

    // 有許多特殊的dailog:文件選擇,MessageBox,顏色選擇,字體選擇,打印預覽,打印
    if( ret == QDialog::Accepted ) 
        qDebug()<<"accepted" ;
    else if( ret== QDialog::Rejected ) 
        qDebug()<<"rejected" ;
#endif 
#if 0
/*文件選擇:這個窗口可以選擇保存文件的名稱,然後將路徑+名稱返回,我們就可以根據返回路徑名來保存文件。*/
    QString strFilename = QFileDialog::getSaveFileName(NULL,
                                                       "Select file for save",
                                                       _strDir,
                                                        "pic file (*.png *.jpg)");
#endif 
#if 0
/*文件選擇:選擇要打開的文件名(絕對路勁);我們就可以根據這個文件路徑來打開相應的文件*/
    QString strFilename = QFileDialog::getOpenFileName(NULL,
                                                       "Select file for open",
                                                       _strDir,
                                                     "pic file (*.png *.jpg)");
#endif
#if 0
    QString strFilename = QFileDialog::getExistingDirectory();

    if(strFilename.isEmpty())
    {
        qDebug() << "select none";
        return;
    }

    qDebug() << strFilename;
    QFileInfo fileInfo(strFilename);
    _strDir = fileInfo.filePath();
    qDebug() << _strDir;
#endif
    //do something for io ... ...
    //上面的選擇將絕對路徑名都給拿下來了,如果要進行保存,不是很容易嗎!
    QPixmap pixmap(this->size()) ;
    QPainter painter(&pixmap) ;
    this->render( &painter ) ;
    pixmap.save(strFilename) ;
#if 0
/*顏色選擇對話框:可以選擇相應的顏色;然後將選擇的顏色返回,這樣我們就可以操作了*/
    QColorDialog colorDia ;
    colorDia.exec() ;
    QColor c = colorDia.selectedColor() ;
#endif
#if 0
/*字體選擇對話框:可以選擇字體;然後將選擇的字體信息返回,我們同樣可以用這些信息來設置相應的值*/
    QFontDialog fontDia ;
    fontDia.exec() ;
    QFont font = fontDia.selectedFont() ;
#endif
#if 0
/*這個也是彈窗對話框,不過只是簡單的選擇以下枚舉中的值,可以嘗試下效果*/
     int ret = QMessageBox::question(this, "????", "realy do .......",
                                    QMessageBox::Yes| QMessageBox::No|
                                    QMessageBox::YesAll| QMessageBox::NoAll);
    if(ret == QMessageBox::Yes)
    {
        qDebug() << "user select yes";
    }
    if(ret == QMessageBox::No)
    {
        qDebug() << "user select no";
    }
    #endif
}


void mydialog::paintEvent( QPaintEvent *ev ) {
}


mydialog::~mydialog(void) { }

三、widget窗口

前面已經介紹過很多繼承這個窗口的控件了,這裏就不再累述。

四、mainWindow窗口

這個也是給人們提供更好的可視化操作;
一個正常window軟件呈現給客戶的可視化界面;
包括:menu菜單、tool工具欄、status狀態欄、電腦顯示屏右下腳的托盤等。

#include "MyWindow.h"


MyWindow::MyWindow(QMainWindow *parent):QMainWindow( parent ) { 

    /*menuBar菜單欄,菜單menu*/
    QMenuBar  *menuBar = this->menuBar() ;
    _menu = menuBar->addMenu( "&File" ) ;
    QMenu *edit = menuBar->addMenu( "&Edit" ) ;

    /*menu菜單中的選項action*/
    QAction *openAction = _menu->addAction( "&Open"
        , this , SLOT(slotOpen()) , QKeySequence::Open  ) ;
    QAction *saveAction = _menu->addAction( "&Save"
        , this , SLOT(slotOpen()) , QKeySequence::Save  ) ;
    _menu->addSeparator() ;//添加分界線
    QAction *closeAction = _menu->addAction( "&Exit"
        , this , SLOT(close()) , QKeySequence::Close  ) ;

    /*toolBar工具欄*/
    QToolBar *toolBar = this->addToolBar( "mimi" ) ;
    toolBar->addAction( openAction ) ;
    toolBar->addAction( saveAction ) ;
    toolBar->addAction( closeAction ) ;
    /*statusBar狀態欄*/
    QStatusBar *statusBar = this->statusBar() ;
    QLabel *label ;
    statusBar->addWidget( label = new QLabel("Ok") ) ;
    label->setText( "<font color=blue>XXXXX... ...</font>" ) ;
    /*上面的三種欄介紹完之後,剩下的窗口區域就是CentralWidget
    **如果將widget直接add到mainwindow這個窗口的話,
    **toolbar是會跟添加進來的widget重疊的*/
    MyView *view = new MyView ;
    this->setCentralWidget( view ) ;
    /*最後就是window系統右下腳的托盤:system tray icon*/
    QSystemTrayIcon *icon = new QSystemTrayIcon ;
    icon->setIcon( QIcon("./1.png") ) ;//圖標
    icon->setToolTip( "luck dog" ) ;//鼠標滑過提示文字
    icon->show() ;//展示在右下角
    icon->setContextMenu( _menu ) ;//右擊出現的菜單
    this->connect( icon , SIGNAL( slotActivated(QSystemTrayIcon::ActivationReason) ) 
        , this , SLOT(slotActivated(QSystemTrayIcon::QSystemTrayIcon::ActivationReason)) ) ;
    this->installEventFilter(this);
}


void MyWindow::slotActivated(QSystemTrayIcon::ActivationReason reason){

    /*這個沒成功*/
    if( reason==QSystemTrayIcon::Trigger ) {
        if( this->isHidden() ) 
            this->show() ;
        else
            this->hide() ;
    }
}


bool MyWindow::eventFilter(QObject *o, QEvent *e)
{
    /*實現什麽功能呢?*/
    if(o == (QObject*)this && e->type() == QEvent::Close)
    {
        return true;
    }

    return QMainWindow::eventFilter(o, e);
}


void MyWindow::slotOpen() {

    QString fileName = QFileDialog::getOpenFileName() ;
    qDebug()<<fileName ;
    /*將打開的文件中的內容顯示在窗口上... ...*/
}
bool MyWindow::event(QEvent *ev)
{
    qDebug() << ev;
    if(ev->type() == QEvent::Close)  {
        return false;
    }
    /*怎麽弄才能實現窗口關閉,托盤還在?*/
    return QMainWindow::event(ev);
}


void MyWindow::paintEvent( QPaintEvent * ) {

    QPainter painter(this) ;
    painter.drawPixmap( QPoint(0,0) , QPixmap("./1.png") ) ;
}


void MyWindow::mousePressEvent( QMouseEvent *ev ) {

    if( ev->button() == Qt::RightButton ) {
        _menu->exec( QCursor::pos() ) ;
    }
}


MyWindow::~MyWindow(void) { }

一、qDebug()函數

  1. qDebug()函數可以直接輸出調試錯誤信息,方便程序員調試信息,查找錯誤;
  2. 例子:qDebug()<<"error"<<endl;

二、QDebug類

  1. 這個函數可以收集錯誤信息,通過QTextStream這個類(之前在寫文件的時候,用過這個類,查看了下函數的作用,果真和自己想的一樣);
  2. QTextStream類,指定一個Qfile*或是QString*作為參數,重載了<<操作符,將對象(QTextStream<<。。)收集到的數據都保存入,相應的參數(這個參數由構造函數決定)中,方便統一管理。例如:在構造時如果指定了文件指針,就直接保存如文件;在構造時如果指定了string,就直接保存如string中… …
  3. 總結:這個錯誤類不是用來輸出信息的(當然簡介使用錯誤函數也是可以輸出信息),更重要的是用來收集錯誤信息,方便統一管理,保存,查看的。
    QString *str ;
    QDebug q( str = new QString("object") ) ;
    q<<"nice";
    qDebug()<< *str ;

Qt基本控件及三大布局