在MainWindow中定義了一個myPushButton的指標。
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void guanbi();
private:
Ui::MainWindow *ui;
myPushButton *nBtn; // <---
};
這個是myPushButton的定義
class myPushButton : public QPushButton
{
Q_OBJECT
public:
explicit myPushButton(QWidget *parent = nullptr);
~myPushButton();
void response();
signals:
void mys(); // <--發射的信號
};
void myPushButton::response()
{
qDebug()<<"response to myclicked!";
}
然后將其同信號mys關聯起來。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
nBtn = new myPushButton;
nBtn->move(100,200);
nBtn->resize(100,50);
nBtn->setText("nPushbutton");
nBtn->setParent(this);
setWindowTitle("test window");
setFixedSize(800,600);
connect(nBtn, &myPushButton::mys, this, &MainWindow::close); // <--關聯信號和槽函式
guanbi(); // <--發射信號
}
MainWindow::~MainWindow()
{
qDebug()<<"MainWindow's destructor!";
delete ui;
}
void MainWindow::guanbi()
{
qDebug()<<"emit signal!";
emit nBtn->mys();
}
根據列印來看,信號是正常發射了,但是MainWindow不能關閉(也就是運行后MainWindow一直顯示,不會關閉)。如果將connect函式換成下面的方式,則response函式能正常運行到,這說明連接信號沒有問題,但是為什么就無法執行close呢?
connect(nBtn, &myPushButton::mys, nBtn, &myPushButton::response);
請教各位,謝謝!
uj5u.com熱心網友回復:
執行guanbi()時,MainWindow還沒進入事件回圈中(在MainWindow的建構式中)uj5u.com熱心網友回復:
那為什么連接換成connect(nBtn, &myPushButton::mys, nBtn, &myPushButton::response),response就能正常執行,不也還是在MainWindow的建構式中嗎,也沒有進入事件回圈呀?
我是新手,不是很懂,謝謝。
uj5u.com熱心網友回復:
connect的函式原型為:
QMetaObject::Connection QObject::connect(const QObject * sender,
const char * signal,
const QObject * receiver,
const char * method,
Qt::ConnectionType type = Qt::AutoConnection);
最后一個引數決定,這個信號槽是直接連接還是佇列連接,默認值是Qt::AutoConnection
對于Qt::AutoConnection的情況:
1、sender和receiver依附執行緒是同一個,就是直接連接
2、sender和receiver依附執行緒不是同一個,就是佇列連接
依附執行緒可以理解為:在哪個執行緒new的就依附哪個執行緒,eg:
A *a = new A; // a的依附執行緒為 thread1
QThread *thread2 = new QThread;
a->moveToThread(thread2); // a的依附執行緒變為 thread2
直接連接:類似直接呼叫函式(立即執行)
佇列連接:將信號放在一個佇列中,等receiver有空了開始執行
connect(nBtn,
&myPushButton::mys,
nBtn,
&myPushButton::response);
是直接連接,myPushButton::mys信號發射時,會立即執行myPushButton::response
connect(nBtn,
&myPushButton::mys,
this,
&MainWindow::close);
也是直接連接,myPushButton::mys信號發射時,也會立即執行MainWindow::close
但是在MainWindow::close中,不是直接就關閉這個視窗,而是向MainWindow發送一個QCloseEvent的事件
QCloseEvent會在事件回圈中分發給MainWindow,在事件分發中可以對事件進行過濾(這些都是后話了)
QApplication a(argc, argv);
...
// 開始事件回圈
// 在事件回圈前呼叫close無效
a.exec();
uj5u.com熱心網友回復:
多謝您的詳細解答,最后再問下:
您上面的回答最后提到“在MainWindow::close中,不是直接就關閉這個視窗,而是向MainWindow發送一個QCloseEvent的事件
QCloseEvent會在事件回圈中分發給MainWindow,在事件分發中可以對事件進行過濾”
那視窗沒有關閉是不是意味著這個事件被過濾掉了,因為即便不直接關閉視窗,但是程式最后總是會進入事件回圈的,等到進入事件回圈后不就可以關閉了?
uj5u.com熱心網友回復:
這問題還真沒有注意過,做了一個測驗:
多載closeEvent,并在QApplication.exec()之前呼叫close()查看是否有運行closeEvent
void Widget::closeEvent(QCloseEvent *event)
{
qDebug() << "Widget::closeEvent";
QWidget::closeEvent(event);
}
測驗結果是有運行closeEvent,和我理解中的有點不太一樣,能力有限,不敢誤人
參考Qt的事件回圈機制: https://blog.csdn.net/simonyucsdy/article/details/82749539
查看QWidget::close的幫助檔案:
Closes this widget. Returns true if the widget was closed; otherwise returns false.
First it sends the widget a QCloseEvent. The widget is hidden if it accepts the close event.
If it ignores the event, nothing happens. The default implementation of QWidget::closeEvent() accepts the close event.
If the widget has the Qt::WA_DeleteOnClose flag, the widget is also deleted. A close events is delivered to the widget no matter if the widget is visible or not.
The QApplication::lastWindowClosed() signal is emitted when the last visible primary window (i.e. window with no parent) with the Qt::WA_QuitOnClose attribute set is closed. By default this attribute is set for all widgets except transient windows such as splash screens, tool windows, and popup menus.
大致的翻譯如下:
關閉此小部件。如果小部件已關閉,則回傳true;否則,回傳false
首先,它向小部件發送QCloseEvent。 如果小部件接受關閉事件,則將其隱藏。
如果它忽略該事件,則什么也不會發生。 QWidget :: closeEvent()的默認實作接受close事件。
如果該小部件具有Qt::WA_DeleteOnClose標志,則該小部件也將被洗掉。 無論小部件是否可見,關閉事件都會傳遞給小部件。
關閉最后一個設定了Qt::WA_QuitOnClose屬性的可見主視窗(即沒有父視窗)時,將發出QApplication :: lastWindowClosed()信號。
默認情況下,為所有視窗小部件設定此屬性,瞬態視窗(例如初始螢屏,工具視窗和彈出選單)除外。
說明:
QWidget::close方法只是隱藏視窗,除非設定了Qt::WA_DeleteOnClose、Qt::WA_QuitOnClose屬性,詳細見:
Qt對話框與視窗的關閉和隱藏(QCloseEvent、Qt::WA_DeleteOnClose屬性、Qt::WA_QuitOnClose屬性)
https://blog.csdn.net/hyongilfmmm/article/details/83247688
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/15897.html
標籤:工具平臺和程序庫
上一篇:資料結構求大神幫忙!!!
下一篇:如何結束行程
