Chapter V Application main window - Qt

Posted by sapna on Thu, 06 Jan 2022 15:54:21 +0100

1, Main window frame

1. Menu bar and toolbar

(1) Menu bar

① Qt provides menu related class components

② QMenuBar class, QMenu class and QAction class
● QMenuBar: the QMenuBar class provides a horizontal menu bar on which different QMenu and qactions can be added. A main window can have only one menu bar.
● QMenu: menus in the menu bar (such as File, Edit, Format, etc.) or menu items with triangular symbols (indicating that there are still sub menus under them) can display text and icons, but they are not responsible for operation, which is somewhat similar to the function of label.
● QAction: Qt abstracts the elements of user interface interaction into an "action", which is represented by QAction class. QAction is the part that is really responsible for executing operations.

Contact: in QMainWindow, you can directly obtain its default QMenuBar menu bar object, add QMenu type menu objects to it (QMenuBar menu bar object), and then add QAction type action objects to the pop-up menu.
code:

QMenuBar* mb = menuBar(); //Call the member function menuBar of QMainWindow, and use this function to get the menu bar object in QMainWindow, that is, the menu bar object in the main window
QMenu* menu = new QMenu("File(&F)");
QAction* action = new QAction("New",NULL);
					
menu->addAction(action); //Add action to the menu item
					
mb->addMenu(menu);  //Add menu items to MenuBar

③ Code mode add menu

// Add edit menu
QMenu *editMenu = ui->menuBar->addMenu(tr("edit(&E)"));
// Add open menu
QAction *action_Open = editMenu->addAction(             
QIcon(":/images/open.png"),tr("Open file(&O)"));
// Set shortcut keys
action_Open->setShortcut(QKeySequence("Ctrl+O"));       
// Add actions to the toolbar
 ui->mainToolBar->addAction(action_Open);     
(2) Toolbar

The toolbar QToolBar class provides a movable panel containing a set of controls. By default, it only displays an action icon, which can be changed in the property bar of QToolBar.
In the designer, you can view the property bar of QToolBar, where the toolButtonStyle property setting icon, the display and relative position of corresponding text, etc; movabel property sets whether the status bar can be moved;
allowedArea sets the allowed docking position; The iconsize property sets the size of the icon; The floatable property sets whether it can float.

For example:
	QToolButton *toolBtn = new QToolButton(this);        // Create QToolButton
	toolBtn->setText(tr("colour"));
	QMenu *colorMenu = new QMenu(this);                  // Create a menu
	colorMenu->addAction(tr("gules"));
	colorMenu->addAction(tr("green"));
	toolBtn->setMenu(colorMenu);                         // add menu
	toolBtn->setPopupMode(QToolButton::MenuButtonPopup); // Set pop-up mode
	ui->mainToolBar->addWidget(toolBtn);           // Add a QToolButton button to the toolbar
	QSpinBox *spinBox = new QSpinBox(this);         // Create QSpinBox
	ui->mainToolBar->addWidget(spinBox);            // Add QSpinBox part to toolbar		

2. Use resource system

The required files (pictures, text, etc.) can be included in the executable files generated by program programming (such as exe files). It ensures that the files used in the program will not be lost and the program will not run incorrectly due to the storage path.

The process of adding a resource system:
	To add a resource file to a project:
		①Right click the project name and select add new file.
		②Then select the added file type as Qt Resource file.
		③Next, name the newly added resource file.
			Note that this resource file name is not the file name of the resources such as pictures you want to add, but the name of the resource file added to the project (this file is used to manage the real resource files to be added later).
		④Then specify which project to add the resource file to. If multiple projects are opened at the same time, you can select them here. If only one project is open, just keep the default.
	To add a resource to a resource file:
		①First, select the resource file in the project, then click the drop-down arrow of the Add button below, and then click "add prefix".
		②The name of the prefix can be taken as needed. It is generally recommended to specify it as the type of resource to facilitate differentiation.
		③After adding the prefix, we can add the file.
		④Find the resource file to add and add it to the project.
	Alias the resource file:
		To alias a resource file, first select the file to be aliased, and then give it an alias.

3. Central component

A central part can be placed in the central area of the main window, which is usually an editor or browser. Single document parts and multi document parts are supported here.
Generally, a part is placed here, and then the layout manager is used to fill the whole central area, and the size can be changed with the size of the window.

4.Dock components

QDockWidget class provides such a component, which can be docked in QMainWindow or suspended as the top-level window of the desktop. We call it Dock component or docked window.
Dock components are generally used to store other components to realize some special functions, just like a toolbox. In the main window, it can be docked around the central part, suspended, dragged anywhere, closed or hidden. A dock part contains a title bar and a content area, and any part can be put into the dock part.

5. Status bar

The QStatusBar class provides a horizontal bar for displaying status information. A status bar is provided by default in QMainWindow.
Status information can be divided into three categories: temporary information, such as general prompt information; Normal information, such as page number and line number; Permanent information, such as version number or date.
You can use the showMessage() function to display a temporary message, which will appear on the far left of the status bar. Generally, a QLabel is added to the status bar with the addWidget() function to display normal information. It will be generated to the left of the status bar and may be covered by temporary messages. If you want to display permanent information, you need to use the addPermanentWidget() function to add a part that can display information like QLabel. It will be generated at the right end of the status bar and will not be masked by temporary messages.
At the far right end of the status bar, there is also a qsizegrid component to adjust the size of the window. You can disable it by using the setsizegridenabled() function.

6. Customize menu

The QWidgetAction class in Qt can realize the function of customizing menus. To implement the custom menu, you need to create a new class that inherits from the QWidgetAction class and re implement the createWidget() function.
Supplement:

(1)emit
	When the object changes the signal and slot state, the signal is transmitted by the object (emit) Out, that's all the object has to do. It doesn't know who's receiving the signal at the other end.
	Code example:	
		signals:  
			void findPrevious(const QString &str, Qt::CaseSensitivity cs);  
			
		private slots:  
			void findClicked();  
			void enableFindButton(const QString &text);  
			
		void FindDialog::findClicked() 
		{				
			Qt::CaseSensitivity cs = caseCheckBox->isChecked() ? Qt::CaseInsensitive : Qt::CaseSensitive;    
			if(backwardCheckBox->isChecked()) 
			{  
				emit findPrevious(text, cs);  
			}  
			else 
			{  
				void findNext(const QString &str, Qt::CaseSensitivity cs);  
				emit findNext(text, cs);  
			}  
		} 
		//emit is to transmit the signal findNext or findPrevious.
		//To put it bluntly, it is to call the slot function corresponding to the findPrevious or findNext signal. Before emit, there must be connect somewhere to associate the signal with the slot,
		//After correlation, emit a signal is equivalent to calling the slot function associated with the signal connect
(2)Qt To create a custom type
	Before you start, you need to ensure that the custom type you create conforms to QMetaType All requirements specified in. In other words, it must provide:
		●A public default constructor
		●A public copy constructor
		●A public destructor
	Below Message The definition of the class contains these members:
		class Message
		{
		public:
			Message();
			Message(const Message &other);
			~Message();
			
			Message(const QString &body, const QStringList &headers);
			
			QString body() const;
			QStringList headers() const;
			
		private:
			QString m_body;
			QStringList m_headers;
		};
		This class also provides a frequently used constructor and two common member functions for obtaining private data.	

2, Rich text processing

Rich Text, or Rich Text format, simply means that multiple formats can be used in documents, such as font color, pictures, tables and so on.

(1) Rich text document structure

Support for rich text processing is provided in Qt. The processing of rich text in Qt is divided into editing operation and read-only operation.

●Editing operation uses some interface functions based on cursor, which better simulates the user's editing operation, is easier to understand, and will not lose the underlying document framework.
●For the overview of document structure, read-only hierarchical interface functions are used, which are conducive to document retrieval and output.

For document reading and editing, two sets of interfaces with different aspects shall be used.

●The cursor of the document is mainly based on QTextCursor class
●The framework of the document is mainly based on QTextDocument class

The structure of a rich text document is represented by several elements:

●Frame( QTextFrame)
●Text block( QTextBlock)
●Forms( QTextTable)
●List( QTextList)

The format of each element is represented by the corresponding format class:

●Frame format( QTextFrameFormat)
●Text block format( QTextBlockFormat)
●Table format( QTextTableFormat)
●List format( QTextListFormat)

These formats are generally used when editing documents, so they are often used with the QTextCursor class.
Because QTextEdit class is a rich text editor, a QTextDocument class object and a QTextCursor class object have been built when building the object of QTextEdit class. Just call them for corresponding operations.
An empty document contains a Root frame, which in turn contains an empty text Block. The framework divides a document into multiple parts. Text blocks, sub frames and tables can be added to the root framework.

① Set root frame

QTextDocument *document = ui->textEdit->document(); //Get document object 
QTextFrame *rootFrame = document->rootFrame();      // Get root frame				
QTextFrameFormat format;                            // Create frame format				
format.setBorderBrush(Qt::red);                     // Boundary color				
format.setBorder(3);                                // Boundary width				
rootFrame->setFrameFormat(format);                  // Frame usage format

② Add subframe

QTextFrameFormat frameFormat; 
frameFormat.setBackground(Qt::lightGray);                // Set background color				
frameFormat.setMargin(10);                               // Set margin				
frameFormat.setPadding(5);                               // Setting up the liner				
frameFormat.setBorder(2);
frameFormat.setBorderStyle(QTextFrameFormat::BorderStyle_Dotted); //Set border style				
QTextCursor cursor = ui->textEdit->textCursor();         // Get cursor				
cursor.insertFrame(frameFormat);                         // Insert frame at cursor
(2) Text block

The text block QTextBlock class provides a container for the text document QTextDocument.
A text block can be regarded as a paragraph, but it cannot use carriage return to wrap lines, because a carriage return to wrap lines means to create a new text block. QTextBlock provides a read-only interface, which is part of the document hierarchical interface mentioned above. If QTextFrame is regarded as one layer, QTextBlock is another layer.
The format of text block is handled by QTextBlockFormat class. It mainly involves alignment, white edges around text block, indentation and so on. The format of the text content in the text block,
For example, font size, bold, underline and other contents are set by QTextCharFormat class.
① Traversal framework

QTextDocument *document = ui->textEdit->document();
QTextFrame *frame = document->rootFrame();
QTextFrame::iterator it;                       // Create an iterator for the QTextFrame class
for (it = frame->begin(); !(it.atEnd()); ++it) {
	QTextFrame *childFrame = it.currentFrame();// Gets the pointer to the current frame
	QTextBlock childBlock = it.currentBlock(); // Gets the current text block
	if (childFrame)
		qDebug() << "frame";
	else if (childBlock.isValid())
		qDebug() << "block:" << childBlock.text();
}

② Traversal subframe

QTextDocument *document = ui->textEdit->document();
QTextBlock block = document->firstBlock();    // Gets the first text block of the document
for (int i = 0; i < document->blockCount(); i++) {
	qDebug() << tr("Text block%1,The first line number of the text block is:%2,Count Reg:%3,The content is:").arg(i).arg(block.firstLineNumber()).arg(block.length())<< block.text();
	block = block.next();                         // Gets the next text block
}

③ Edit the formatting of text blocks and their contents

QTextCursor cursor = ui->textEdit->textCursor();
QTextBlockFormat blockFormat;      // Text block format
blockFormat.setAlignment(Qt::AlignCenter); // horizontally
cursor.insertBlock(blockFormat);   // Use text block format
QTextCharFormat charFormat;// Character format
charFormat.setBackground(Qt::lightGray);   // Background color
charFormat.setForeground(Qt::blue);// Font color
// Use Arial, size 12, bold, italic
charFormat.setFont(QFont(tr("Song typeface"), 12, QFont::Bold, true)); 
charFormat.setFontUnderline(true); // Use underline
cursor.setCharFormat(charFormat);  // Use character format
cursor.insertText(tr("Test font")); // insert text
(3) Tables, lists, and pictures
//Insert table   
QTextCursor cursor = ui->textEdit->textCursor();
QTextTableFormat format;          // Table format
format.setCellSpacing(2);         // White outside the table
format.setCellPadding(10);        // White inside the table
cursor.insertTable(2, 2, format); // Insert 2 Row 2 column table
//Insert list
QTextListFormat format;           // List format
format.setStyle(QTextListFormat::ListDecimal);   // Number
ui->textEdit->textCursor().insertList(format);
//Insert picture
QTextImageFormat format;          // Picture format
format.setName("logo.png");       // Picture path
ui->textEdit->textCursor().insertImage(format);
(4) Find function
//find text   
QDialog *dlg = new QDialog(this);         // create a dialog box
lineEdit = new QLineEdit(dlg);            // Create row editor
QPushButton *btn = new QPushButton(dlg);  // Create button
btn->setText(tr("Find next"));
connect(btn,SIGNAL(clicked()),this,SLOT(findNext())); // Associated signals and slots
QVBoxLayout *layout = new QVBoxLayout;    // Create vertical layout manager
layout->addWidget(lineEdit);              // Add part
layout->addWidget(btn);
dlg->setLayout(layout);                   // Using the layout manager in a dialog box
dlg->show();
 
//Find next
QString string = lineEdit->text();
// Use the lookup function to find the specified string. The lookup method is backward
bool isfind = ui->textEdit->find(string, QTextDocument::FindBackward);
if(isfind){                // If the search is successful, the number of the row and column where the output string is located
	qDebug() << tr("Line number:%1 Column number:%2")
				.arg(ui->textEdit->textCursor().blockNumber())
				.arg(ui->textEdit->textCursor().columnNumber());
}
(5) Syntax highlighting

When editing code with Qt Creator, you can find that different colors will be displayed when entering keywords, which is the so-called syntax highlighting.
Qsyntaxhighlight class is provided in Qt's rich text processing to realize syntax highlighting. In order to realize this function, you need to create a subclass of qsyntaxhighlight class, and then re implement the highlightBlock() function. When using, you can directly take the QTextDocument class object pointer as its parent part pointer, so that the highlightBlock() function can be called automatically.
The custom class is mysyntaxhighlight, which can be used like this:

highlighter = new MySyntaxHighlighter(ui->textEdit->document()); 

Re implement the highlightBlock() function:

QTextCharFormat myFormat;             // Character format
myFormat.setFontWeight(QFont::Bold);
myFormat.setForeground(Qt::green);
QString pattern = "\\bchar\\b";       // The character to match, here is the word "char"
QRegExp expression(pattern);          // Create regular expressions
int index = text.indexOf(expression); // Match string from position 0
// If the match is successful, the return value is the starting position of the string, which is greater than or equal to 0
while (index >= 0) {    
	int length = expression.matchedLength(); // Length of string to match
	setFormat(index, length, myFormat);      // Format the string to match
	index = text.indexOf(expression, index + length); // Continue matching
}
//Here, we mainly use regular expressions and indexOf() function of QString class to perform word processing
(6)HTML

Support for HTML subsets is also provided in rich text processing. You can use HTML tags or CSS attributes when adding text in QLabel or QTextEdit, for example:

ui->textEdit->append(tr("<h1><font color=red>use HTML</font></h1>")); 

3, Drag and drop operation

Class used and inheritance relationship

Drag and drop includes two actions: drag and drop. When dragged, the dragged data will be stored as objects of MIME type (see Chapter 6 file dialog box). The MIME type is described by QMimeData class.
MIME types are usually used by clipboard and drag and drop systems to identify different types of data.

●Drag point(drag site): The starting position of the drag.
●Put it down(drop site): The drop position of the dragged object. If the part cannot accept the dragged object, Qt Changes the shape of the cursor(A disabled shape)To explain to the user.

1. Start and end of drag and drop

Start drag and drop: drag and drop is started by calling QDrag::exec() function, which is a blocking function (but does not block the main event loop), which means that the function will not be returned before the drag and drop operation is completed. After calling QDrag::exe() function, Qt has the ownership of the dragged object and will delete it if necessary.
End drag and drop: end drag and drop when the user drops the drag or cancels the drag operation.

2. Drag and drop process and events

After starting drag and drop, the data will be dragged. At this time, you need to press and hold the mouse button to drag the data to be dragged. Releasing the mouse button means that the drag is over. During this period, the following events will occur
By default, the assembly does not accept drop events. Use the QWidget::setAcceptDrops() function to set whether the part accepts drop events (that is, the events sent when drag and drop is completed).
The following events occur only when the part accepts a drop event.

① QDragEnterEvent: drag into the event. When the drag operation enters the part, the event is sent to the part. Ignoring the event will lead to that the subsequent drag and drop events cannot be sent. At this time, the cursor will usually be displayed as a disabled graphic on the appearance of the part.
② QDragMoveEvnet: drag move event. This event is sent when the drag operation is in progress and when the modifier key of the keyboard (such as Ctrl) is pressed when there is focus. In order for the part to receive this event, the part must accept the QDragEnterEvent event event.
③ QDropEvent: drop the event. This event is sent when the drag and drop operation is completed, that is, when the user drops an object on the part. In order for the part to receive this event, the part must accept the QDragEnterEvent event event and cannot ignore the QDragMoveEvnt event.
④ QDragLeaveEvent: this event is sent when the drag and drop operation leaves the part. Note: to enable the part to receive this event, the drag must first enter the part (i.e. generate QDragEnterEvent event) and then leave the part before generating QDragLeaveEvent event. Since this event is rarely used, this article will not focus on it.

Note: must accept means that the handler of the event must be re implemented and the event must be accepted. Cannot ignore means that the ignore() function is not explicitly called in the processing function to ignore the event.

3. Steps to write a drag and drop program

● call QWidget::setAcceptDrops() function on the part that needs to accept drop data to enable the part to accept drag and drop events.
● start drag and drop: usually start drag and drop in mousePressEvent() or mouseMoveEvent() functions. Remember that starting drag and drop is to call exec() function of QDrag object, so you can also start drag and drop in keyPressEvent() and other functions (because this is rarely done, it will not be introduced in this article). In this step, save the data to be dragged in the QMimeData object.
● re implement the dragEnterEvent() event handler function of the component that needs to accept the dropped data.
● re implement the dragMoveEvent or dropEvent() function as needed

4, Print document

Print settings
The QPrinter class is a class for print settings.

1.OutputFormat

explain:
QPrinter output file format, QPrinter::PdfFormat will input pdf file format, QPrinter:: Postscript format will input ps file format The file type generated after executing print() in is based on this.
Correlation function:

OutputFormat QPrinter::outputFormat () //current format			
void QPrinter::setOutputFormat ( OutputFormat format )//Format			
void QPrinter::setOutputFileName ( const QString & fileName )//If the file name suffix is set to ps, it is ps format, and if the suffix is PDF, it is pdf format	

2. Other parameters

Orientation: Paper orientation, yes QPrinter::Portrait(portrait)and QPrinter::Landscape(transverse)
void QPrinter::setOrientation ( Orientation orientation )
Orientation QPrinter::orientation ()
PaperSize:   Paper size, with A4 etc.
void QPrinter::setPaperSize ( PaperSize newPaperSize )
PaperSize QPrinter::paperSize ()	

3. Output as file:

The following controls can be used as input:
① QWebView, QWebFrame, as the carrier of html file format;
② QPlainTextEdit, QTextEdit, single line / multi line text editing area;
③ QPainter, a class for drawing, which can process files in picture format;
④ QPrintPreviewWidget, a control specially used for print preview;
⑤ QTextDocument, document processing of document type;
The above controls have one thing in common. They all have a print() function. You can pass in the set QPrinter and output the corresponding file.

(1)QWebView and QWebFrame
Purpose: as html Carrier of file format
 Processing function:
	void QWebView::print ( QPrinter * printer )			
	void QTextDocument::print ( QPrinter * printer )		
Example:		
	//Global variables		
	QWebView *webview=0;
	QPrinter *printer=0;		
	void printWebView(void)		
	{		
		if(webview!=0)		
		{		
			webview = new QWebView();		
		}		
		if(webview!=0)		
		{		
			printer = new QPrinter(QPrinter::PrinterResolution);		
		}		
		 webview->load(QUrl("file:///home/root/test.html"));		
		//Because loading takes time, printing cannot be processed until loading is completed		
		connect(webview,SIGNAL(loadFinished(bool)),this,SLOT(loadend (bool)));		
	}		
	void loadend(bool ok)		
	{		
		webview->print(printer);//Output print file		
	}		
(2)QPlainTextEdit and QTextEdit
Purpose: a control for interface text input
 Processing function:	
	void QPlainTextEdit::print ( QPrinter * printer )			
	void QTextEdit::print ( QPrinter * printer )		
Example:		
	void prinTextEdit(void)		
	{		
		QTextEdit *edt = new QTextEdit();		
		QPrinter *printer = new QPrinter(QPrinter::PrinterResolution); 		
		edt->setText("This is an text!");    		
		edt->print(printer);	
		delete printer;		
		delete edt;		
	}		
(3)QPainter
Purpose: class for drawing
 Processing function:	
	QPainter ( QPaintDevice * device )		
Example:	
	void prinTextEdit(void)		
	{		
		QImage image("/home/root/test.jpg");		
		QPainter painter(printer);		
		QRect rect = painter.viewport();		
		QSize size = image.size();		
		size.scale(rect.size(), Qt::KeepAspectRatio);		
		painter.setViewport(rect.x(), rect.y(),size.width(), size.height());		
		painter.setWindow(image.rect());		
		painter.drawImage(0, 0, image);
		painter.drawText(10,10, "this is image");		
	}	
(4)QPrintPreviewWidget
Purpose: a control specially used for print preview		
Processing function:		
	QPrintPreviewWidget::QPrintPreviewWidget ( QPrinter * printer, QWidget * parent = 0, Qt::WindowFlags flags = 0 )	
	void QPrintPreviewWidget::print ()	
Example:		
	QTextEdit edt;		
	void prinTextEdit(void)		
	{		
		QPrinter *printer = new QPrinter(QPrinter::PrinterResolution);		
		QPrintPreviewWidget *preview = new QPrintPreviewWidget (printer);		
		connect(previewWidget,SIGNAL(paintRequested(QPrinter*)),this,SLOT(printPreview(QPrinter *)));//Associate the contents of the print preview		
		preview ->print();		
		delete printer;		
		delete preview;		
	}		
	void printPreview(QPrinter *printer)		
	{		
		edt.setText("This is an text!");		
		edt.print(printer);		
	}		
(5)QTextDocument
Purpose: document type file processing		
Processing function:		
	void QTextDocument::print ( QPrinter * printer )  		

4. Output to device

The output ps file format can be used as the input file of the printer driver.
In qt, you can use the following commands:
QString cmd;//cmd is set as the command for printing. Driver support is required.
system(cmd);

5. Related controls

Qt provides some standard controls.
QPrintDialog, print dialog
QPrintPreviewDialog, print preview dialog

Topics: Qt