Qt/C++開發經驗小技巧281-285

  1. 懸停窗體QDockWidget默認在標題欄右鍵會彈出懸停模塊的顯示隱藏菜單,如果需要去掉,會發現設置Qt::NoContextMenu或者事件過濾器攔截都是無效的,必須設置 dockWidget->setContextMenuPolicy(Qt::PreventContextMenu); 。

  2. Qt中的佈局有個默認的margin邊距值和spacing間距值,在沒有設置該值的情況下,會根據運行的環境自動設置該值,比如1080P分辨率和2k分辨率的電腦,該值的默認值不一樣,並不是你在UI設計的時候屬性欄中看到的值,這個要特別注意,你看到的7可能在目標平臺運行的時候是11,如果一定要按照你想要的值來運行,可以重新設置即可,設置過哪一個就該值按照設定的來。如果不想一個個設置調整佈局中的間距邊距,你需要用到萬能大法樣式代理,繼承QProxyStyle類然後重新設置樣式即可。該方式也是屬於鬥皇級別的UI外觀控制策略,最終所有的qss樣式也是要通過該樣式去繪製的,意味着這裏你可以重新定義和控制所有控件的外觀樣式,非常的強大。

//也可以繼承Qt內置的樣式比如 QFusionStyle/QCleanlooksStyle
class QCustomStyle : public QProxyStyle
{
public:
    int pixelMetric(PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const {

        if (metric == QStyle::PM_LayoutHorizontalSpacing || metric == QStyle::PM_LayoutVerticalSpacing) {
            //將佈局中的橫向和垂直間距設置成10
            return 10;
        } else if (metric == QStyle::PM_ButtonMargin) {
            //將所有按鈕的margin邊距設置成20
            return 20;
        }
        return QProxyStyle::pixelMetric(metric, option, widget);
    }
};

qApp->setStyle(new QCustomStyle);
  1. 養成良好的編程習慣至關重要,尤其是對變量的初始化,包括一些類對象的定義後也務必記得初始化,否則在不初始化的時候,默認值飄忽不定,比如int默認值在debug/release下以及不同編譯器下默認值都不一樣,甚至在頭文件定義以及函數中定義都可能不同的默認值,下面表格中整理的測試的值,對應的int值飄忽不定的。常見的默認初始化定義建議 int i = 0; bool b = false; class a = NULL;
版本 定義位置 debug/release int bool
Qt4.7/mingw 頭文件 debug 7077464 true
Qt4.7/mingw 頭文件 release 48 true
Qt4.7/mingw 函數中 debug 2162216 false
Qt4.7/mingw 函數中 release 0 false
Qt5.7/msvc 頭文件 debug -1 true
Qt5.7/msvc 頭文件 release -1 true
Qt5.7/msvc 函數中 debug 1898108572 false
Qt5.7/msvc 函數中 release 18872512 true
Qt6.5/mingw 頭文件 debug -1305540880 true
Qt6.5/mingw 頭文件 release -1124044992 true
Qt6.5/mingw 函數中 debug 0 false
Qt6.5/mingw 函數中 release 0 false
  1. 對QTableView進行全部選中、全部不選、反向選中操作。
void frmXXX::initAction()
{
    QAction *actionAll = new QAction("全部選中");
    QAction *actionInvert = new QAction("反向選中");
    QAction *actionClear = new QAction("清空選中");
    connect(actionAll, SIGNAL(triggered(bool)), this, SLOT(doAction()));
    connect(actionInvert, SIGNAL(triggered(bool)), this, SLOT(doAction()));
    connect(actionClear, SIGNAL(triggered(bool)), this, SLOT(doAction()));

    ui->tableView->addAction(actionAll);
    ui->tableView->addAction(actionInvert);
    ui->tableView->addAction(actionClear);
    ui->tableView->setContextMenuPolicy(Qt::ActionsContextMenu);
}

void frmXXX::doAction()
{
    QAction *action = (QAction *)sender();
    QString text = action->text();
    if (text == "全部選中") {
        ui->tableView->selectAll();
    } else if (text == "反向選中") {
        //找到所有選中的行集合
        QList<int> rows;
        QModelIndexList list = ui->tableView->selectionModel()->selectedRows();
        int count = list.count();
        for (int i = 0; i < count; ++i) {
            rows << list.at(i).row();
        }

        //先清空所有選中
        ui->tableView->clearSelection();
        //不在選中行集合的則選中
        count = ui->tableView->model()->rowCount();
        for (int i = 0; i < count; ++i) {
            if (!rows.contains(i)) {
                ui->tableView->selectRow(i);
            }
        }
    } else if (text == "清空選中") {
        ui->tableView->clearSelection();
    }
}
  1. pro文件中多重條件判斷,前面 ! 表示非,中間 | 表示或(兩個條件滿足其一),中間 :: 表示與(兩個條件都要滿足)。
//下面表示安卓或者ios平臺
android|ios {}

//下面表示非安卓和ios平臺
!android::!ios {}

國內站點:https://gitee.com/feiyangqingyun
國際站點:https://github.com/feiyangqingyun

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章