博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Ubuntu18.04中配置QT5.11开发环境
阅读量:5786 次
发布时间:2019-06-18

本文共 25447 字,大约阅读时间需要 84 分钟。

准备工作

参考  .

# 安装g++sudo apt install build-essential# sudo apt install libfontconfig1 # 安装openGL支持 sudo apt install mesa-common-dev libglu1-mesa-dev

从直接下载安装包, 地址是

执行chmod u+x使其可执行

安装

直接运行 qt-opensource-linux-x64-5.11.1.run, 会出现安装界面, 这一步可以配置网络代理, 往下进行需要填写自己在QT注册的账户和口令, 会进行在线验证.

设置安装目录时, 可以将路径配置到/opt下, 例如 /opt/qt/Qt5.11.1, 会在最后一步时弹出提示输入su口令.

组件选择: 如果空间足够的话, 除了一个deprecated的以外, 都选上吧. 实测, 整个安装下来占地5.4GB

然后就可以在菜单中找到Qt Creator, 启动似乎非常快, 一秒不到就打开界面了, 完全不像一个数百MB的程序啊

运行一个例子

在网上找了一个例子, 项目名叫First, 但是编译中出现了错误

$ gcc   first.o all   -o firstgcc: error: all: No such file or directory

这个是因为文件名称first引起了歧义. 将项目名改为MyFirst就正常编译通过了.

原因说明  

The Makefile contains a generated (fake) target called "first" and it also contains a set of explicit and implied rules related to the source file "first.cpp". The make command builds your TARGET (which is named after the directory if not specified) and then decides that because "first.o" changed it must rebuild the "first" target: at this point it gets confused.

$ make/usr/bin/moc -DQT_NO_DEBUG -DQT_SQL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtSql -I/usr/include/qt4 -I. -I. first.cpp -o first.mocg++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_SQL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtSql -I/usr/include/qt4 -I. -I. -o first.o first.cppg++ -Wl,-O1 -Wl,-rpath,/usr/lib/qt4 -o simple_example first.o    -L/usr/lib/qt4 -lQtSql -L/usr/lib/mysql -L/usr/lib/qt4 -lQtGui -L/usr/X11R6/lib -lQtCore -lgthread-2.0 -lrt -lglib-2.0 -lpthreadgcc   first.o all   -o first   // <<<<< confused, decides to rebuild "first" target using a file called "all"gcc: all: No such file or directorymake: *** [first] Error 1

You get similar confusion (that make recovers from) if "TARGET = first" even with no files called "first.cpp".

$ make/usr/bin/moc -DQT_NO_DEBUG -DQT_SQL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtSql -I/usr/include/qt4 -I. -I. main.cpp -o main.mocg++ -c -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_SQL_LIB -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4/QtSql -I/usr/include/qt4 -I. -I. -o main.o main.cppmake: Circular all <- first dependency dropped.   // <<<< confused but recognises the situationg++ -Wl,-O1 -Wl,-rpath,/usr/lib/qt4 -o first main.o    -L/usr/lib/qt4 -lQtSql -L/usr/lib/mysql -L/usr/lib/qt4 -lQtGui -L/usr/X11R6/lib -lQtCore -lgthread-2.0 -lrt -lglib-2.0 -lpthread

Adding

.PHONY = first

to Makefile fixes this problem but probably generates another if the TARGET = first. The change would be overwritten by qmake anyway. Easier to just avoid it.

Qt5常用快捷键

F2  跳转到变量的声明, 切换函数的声明和实现

F4  在头文件和C文件之间切换
Ctrl + B 构建
Ctrl + R 运行

Qt5教程

bogotobogo.com的这个教程不错, 值得推荐 

一个带菜单的图片浏览器例子

来源是

其中的主要部分代码为

MenuWindow.pro

#-------------------------------------------------## Project created by QtCreator 2018-08-27T14:02:44##-------------------------------------------------QT       += core guiQT       += printsupportgreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = MenuWindowTEMPLATE = app# The following define makes your compiler emit warnings if you use# any feature of Qt which has been marked as deprecated (the exact warnings# depend on your compiler). Please consult the documentation of the# deprecated API in order to know how to port your code away from it.DEFINES += QT_DEPRECATED_WARNINGS# You can also make your code fail to compile if you use deprecated APIs.# In order to do so, uncomment the following line.# You can also select to disable deprecated APIs only up to a certain version of Qt.#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0SOURCES += \        main.cpp \        mainwindow.cpp \    mydialog.cppHEADERS += \        mainwindow.h \    mydialog.hFORMS += \        mainwindow.ui \    mydialog.ui

mainwindow.h

#ifndef MAINWINDOW_H#define MAINWINDOW_H#include 
#include
#include
#include
#include
#include "mydialog.h"namespace Ui {class MainWindow;}class MainWindow : public QMainWindow{ Q_OBJECTpublic: explicit MainWindow(QWidget *parent = 0); ~MainWindow();private slots: void open(); void print(); void zoomIn(); void zoomOut(); void normalSize(); void fitToWindow(); void about(); void newWindow();private: Ui::MainWindow *ui; MyDialog *myDialog; QLabel *imageLabel; QScrollArea *scrollArea; QMenu *fileMenu; QMenu *viewMenu; QMenu *helpMenu; QAction *openAct; QAction *printAct; QAction *newWindowAct; QAction *exitAct; QAction *zoomInAct; QAction *zoomOutAct; QAction *normalSizeAct; QAction *fitToWindowAct; QAction *aboutAct; QAction *aboutQtAct; double scaleFactor; void updateActions(); void scaleImage(double factor); void adjustScrollBar(QScrollBar *scrollBar, double factor);};#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"#include "ui_mainwindow.h"#include 
#include
#include
#ifndef QT_NO_PRINTER#include
#endifMainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); openAct = new QAction(tr("&Open..."), this); openAct->setShortcut(tr("Ctrl+O")); printAct = new QAction(tr("&Print..."), this); printAct->setShortcut(tr("Ctrl+P")); printAct->setEnabled(false); newWindowAct = new QAction(tr("&New Window"), this); newWindowAct->setShortcut(tr("Ctrl+N")); exitAct = new QAction(tr("E&xit"), this); exitAct->setShortcut(tr("Ctrl+Q")); zoomInAct = new QAction(tr("Zoom &In (25%)"), this); zoomInAct->setShortcut(tr("Ctrl+=")); //(Ctrl)(+) zoomInAct->setEnabled(false); zoomOutAct = new QAction(tr("Zoom &Out (25%)"), this); zoomOutAct->setShortcut(tr("Ctrl+-")); //(Ctrl)(-) zoomOutAct->setEnabled(false); normalSizeAct = new QAction(tr("&Normal Size"), this); normalSizeAct->setShortcut(tr("Ctrl+S")); normalSizeAct->setEnabled(false); fitToWindowAct = new QAction(tr("&Fit to Window"), this); fitToWindowAct->setEnabled(false); fitToWindowAct->setCheckable(true); fitToWindowAct->setShortcut(tr("Ctrl+F")); aboutAct = new QAction(tr("&About"), this); aboutQtAct = new QAction(tr("About &Qt"), this); fileMenu = new QMenu(tr("&File"), this); fileMenu->addAction(openAct); fileMenu->addAction(printAct); fileMenu->addAction(newWindowAct); fileMenu->addSeparator(); fileMenu->addAction(exitAct); viewMenu = new QMenu(tr("&View"), this); viewMenu->addAction(zoomInAct); viewMenu->addAction(zoomOutAct); viewMenu->addAction(normalSizeAct); viewMenu->addSeparator(); viewMenu->addAction(fitToWindowAct); helpMenu = new QMenu(tr("&Help"), this); helpMenu->addAction(aboutAct); helpMenu->addAction(aboutQtAct); menuBar()->addMenu(fileMenu); menuBar()->addMenu(viewMenu); menuBar()->addMenu(helpMenu); imageLabel = new QLabel(this); imageLabel->setBackgroundRole(QPalette::Base); imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); imageLabel->setScaledContents(true); scrollArea = new QScrollArea(this); scrollArea->setBackgroundRole(QPalette::Dark); scrollArea->setWidget(imageLabel); setCentralWidget(scrollArea); setWindowTitle(tr("Image Viewer")); resize(500, 400); connect(openAct, SIGNAL(triggered()), this, SLOT(open())); connect(printAct, SIGNAL(triggered()), this, SLOT(print())); connect(exitAct, SIGNAL(triggered()), this, SLOT(close())); connect(zoomInAct, SIGNAL(triggered()), this, SLOT(zoomIn())); connect(zoomOutAct, SIGNAL(triggered()), this, SLOT(zoomOut())); connect(normalSizeAct, SIGNAL(triggered()), this, SLOT(normalSize())); connect(fitToWindowAct, SIGNAL(triggered()), this, SLOT(fitToWindow())); connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); connect(newWindowAct, SIGNAL(triggered(bool)), this, SLOT(newWindow()));}MainWindow::~MainWindow() { delete ui;}void MainWindow::open() { QString fileName = QFileDialog::getOpenFileName(this, tr("Open File"), QDir::currentPath()); if (!fileName.isEmpty()) { QImage image(fileName); if (image.isNull()) { QMessageBox::information(this, tr("Image Viewer"), tr("Cannot load %1.").arg(fileName)); return; } imageLabel->setPixmap(QPixmap::fromImage(image)); scaleFactor = 1.0; printAct->setEnabled(true); fitToWindowAct->setEnabled(true); updateActions(); if (!fitToWindowAct->isChecked()) imageLabel->adjustSize(); }}void MainWindow::print() {}void MainWindow::newWindow() { myDialog = new MyDialog(this); myDialog->resize(300, 200); /*myDialog->setModal(true); myDialog->exec();*/ myDialog->show();}void MainWindow::zoomIn() { scaleImage(1.25);}void MainWindow::zoomOut() { scaleImage(0.8);}void MainWindow::normalSize() { imageLabel->adjustSize(); scaleFactor = 1.0;}void MainWindow::fitToWindow() { bool fitToWindow = fitToWindowAct->isChecked(); scrollArea->setWidgetResizable(fitToWindow); if (!fitToWindow) { normalSize(); } updateActions();}void MainWindow::about() { QMessageBox::about(this, tr("About Image Viewer"), tr("
Image Viewer example."));}void MainWindow::updateActions() { zoomInAct->setEnabled(!fitToWindowAct->isChecked()); zoomOutAct->setEnabled(!fitToWindowAct->isChecked()); normalSizeAct->setEnabled(!fitToWindowAct->isChecked());}void MainWindow::scaleImage(double factor) { Q_ASSERT(imageLabel->pixmap()); scaleFactor *= factor; imageLabel->resize(scaleFactor * imageLabel->pixmap()->size()); adjustScrollBar(scrollArea->horizontalScrollBar(), factor); adjustScrollBar(scrollArea->verticalScrollBar(), factor); zoomInAct->setEnabled(scaleFactor < 3.0); zoomOutAct->setEnabled(scaleFactor > 0.333);}void MainWindow::adjustScrollBar(QScrollBar *scrollBar, double factor){ int value = scrollBar->value(); int step = scrollBar->pageStep(); value = int(factor * value + ((factor - 1) * step/2)); scrollBar->setValue(value);}

QScrollBar组件

结合Qt5中对于QScrollBar的说明, 对void MainWindow::scaleImage(double factor) 和 void MainWindow::adjustScrollBar(QScrollBar *scrollBar, double factor) 这两个方法进行分析.

 

a. 这是滚动条的滑块, 提供了快速的定位, 但是不能提供精确的定位

b. 箭头按钮用于精确地浏览定位, 对于文本编辑器, 典型的步长是一行, 而对于图片则是20像素.
c. 翻页控制部分, 点击的效果等价于一次翻页, 正常情况下, 一个翻页对于scrollbar的value的变化等于滑块的长度.
每个滚动条有一个value字段, 用于标示此滑块距离滚动条起点的距离. 这个值一定是介于 minimum() 和 maximum() 之间. 在 minimum value和 maximum value时, 滑块的位置分别如上图所示. 所以要注意, 这个滚动条的长度并非等于maximum().

由此可知, 对于前面例子中图片放大factor倍时, 对于scrollbar.value:

1. 如果value不变, 那么当图片放大时, 因为maximum value增大, 故滑块一边缩小, 一边位置会往起始方向收缩
2. 如果value与factor进行同等比例的放大, 那么滑块一边缩小, 一边起始边界的位置保持不变
3. 如果value与factor进行同等比例放大的同时, 增加滑块长度(pageStep)的收缩长度, 那么滑块一边缩小, 一边中心位置保持不变. 所以上面adjustScrollBar()方法的处理为

value = int(factor * value + ((factor - 1) * step/2));

Qt5的Layout

常用的Layout主要有以下几种

  • QHBoxLayout 将组件按水平进行布局, 宽度平均分割, 高度占满外框
  • QVBoxLayout 将组件按垂直进行布局, 高度平均分割, 宽度占满外框
  • QGridLayout 将组件按表格进行布局, 类似于HTML中的table tr td, 可以水平跨列, 也可以垂直跨行
  • QFormLayout 用于有多个成对的标签+输入的界面, 可以设置不同风格以及在宽带不足时自动换行
  • QGraphicsAnchorLayout 用于在组件上添加锚点, 并以锚点的相对位置来控制布局
  • QStackedLayout 对于内部的组件, 每次只显示一个(可以用于制作标签页)

而在主窗口中, 常用的底层布局并非Layout, 而是QSplitter. 这个自带了对内部widget的自动拉伸, 以及分隔栏的鼠标拖动调整,非常方便. 可以参考Redis Desktop Manager的布局设计(是qml格式的, 但是可以看出来布局的设计) 

import QtQuick 2.0import QtQuick.Layouts 1.1import QtQuick.Controls 1.4import QtQuick.Controls.Styles 1.1import QtQuick.Dialogs 1.2import QtQml.Models 2.2import QtQuick.Window 2.2import Qt.labs.settings 1.0import "."import "./common"import "./common/platformutils.js" as PlatformUtilsimport "./value-editor"import "./connections-tree"import "./console"import "./server-info"import "./bulk-operations"ApplicationWindow {    id: approot    visible: true    objectName: "rdm_qml_root"    title: "Redis Desktop Manager " + Qt.application.version    width: 1100    height: 800    property double wRatio : (width * 1.0) / (Screen.width * 1.0)    property double hRatio : (height * 1.0) / (Screen.height * 1.0)    property var currentValueFormatter    Component.onCompleted: {        if (hRatio > 1 || wRatio > 1) {            console.log("Ratio > 1.0. Resize main window.")            width = Screen.width * 0.9            height = Screen.height * 0.8        }        if (PlatformUtils.isOSXRetina(Screen)) {            bottomTabView.implicitHeight = 100        }    }    Settings {        category: "windows_settings"        property alias x: approot.x        property alias y: approot.y        property alias width: approot.width        property alias height: approot.height    }    SystemPalette {        id: sysPalette    }    FontLoader {        id: monospacedFont        Component.onCompleted: {            source = "qrc:/fonts/Inconsolata-Regular.ttf"        }    }    QuickStartDialog {        id: quickStartDialog        objectName: "rdm_qml_quick_start_dialog"        width: PlatformUtils.isOSX() ? 600 : approot.width * 0.8    }    GlobalSettings {        id: settingsDialog    }    ConnectionSettignsDialog {        id: connectionSettingsDialog        objectName: "rdm_connection_settings_dialog"        onTestConnection: {                                   if (connectionsManager.testConnectionSettings(settings)) {                hideLoader()                showMsg(qsTr("Successful connection to redis-server"))            } else {                hideLoader()                showError(qsTr("Can't connect to redis-server"))            }                    }        onSaveConnection: connectionsManager.updateConnection(settings)    }    MessageDialog {        id: notification        objectName: "rdm_qml_error_dialog"        visible: false        modality: Qt.WindowModal        icon: StandardIcon.Warning        standardButtons: StandardButton.Ok        function showError(msg) {            icon = StandardIcon.Warning            text = msg            open()        }        function showMsg(msg) {            icon = StandardIcon.Information            text = msg            open()        }    }    BulkOperationsDialog {        id: bulkOperationDialog    }    Connections {        target: bulkOperations        onOpenDialog: {            bulkOperationDialog.operationName = operationName            bulkOperationDialog.open()        }    }    Connections {        target: connectionsManager        onEditConnection: {            connectionSettingsDialog.settings = config            connectionSettingsDialog.open()        }        onError: {                        notification.showError(err)        }        Component.onCompleted: {            if (connectionsManager.size() == 0)                quickStartDialog.open()        }    }    toolBar: AppToolBar {}    BetterSplitView {        anchors.fill: parent        orientation: Qt.Horizontal                BetterTreeView {            id: connectionsTree            Layout.fillHeight: true            Layout.minimumWidth: 350            Layout.minimumHeight: 500        }        BetterSplitView {            orientation: Qt.Vertical            BetterTabView {                id: tabs                objectName: "rdm_qml_tabs"                currentIndex: 0                Layout.fillHeight: true                Layout.fillWidth: true                Layout.minimumWidth: 650                Layout.minimumHeight: 30                onCurrentIndexChanged: {                    if (tabs.getTab(currentIndex).tabType) {                        if (tabs.getTab(currentIndex).tabType == "value") {                            var realIndex = currentIndex - serverStatsModel.tabsCount();                            if (welcomeTab) {                                realIndex -= 1                            }                            viewModel.setCurrentTab(realIndex);                        } else if (tabs.getTab(currentIndex).tabType == "server_info") {                            var realIndex = currentIndex;                            if (welcomeTab) {                                realIndex -= 1                            }                            serverStatsModel.setCurrentTab(index);                        }                    }                }                WelcomeTab {                    id: welcomeTab                    clip: true                    objectName: "rdm_qml_welcome_tab"                    property bool not_mapped: true                    onClose: tabs.removeTab(index)                    function closeIfOpened() {                        var welcomeTab = tabs.getTab(0)                        if (welcomeTab && welcomeTab.not_mapped)                            tabs.removeTab(0)                    }                }                ServerInfoTabs {                    model: serverStatsModel                }                Connections {                    target: serverStatsModel                    onRowsInserted: if (welcomeTab) welcomeTab.closeIfOpened()                }                ValueTabs {                    objectName: "rdm_qml_value_tabs"                    model: valuesModel                }                AddKeyDialog {                    id: addNewKeyDialog                    objectName: "rdm_qml_new_key_dialog"                    width: approot.width * 0.7                    height: {                        if (approot.height > 500) {                            return approot.height * 0.7                        } else {                            return approot.height                        }                    }                }                Connections {                    target: valuesModel                    onKeyError: {                        if (index != -1)                            tabs.currentIndex = index                        notification.showError(error)                    }                    onRowsInserted: {                        if (welcomeTab) welcomeTab.closeIfOpened()                    }                    onNewKeyDialog: addNewKeyDialog.open()                }            }            BetterTabView {                id: bottomTabView                Layout.fillWidth: true                Layout.minimumHeight: PlatformUtils.isOSXRetina()? 15 : 30                tabPosition: Qt.BottomEdge                Consoles {                    objectName: "rdm_qml_console_tabs"                    model: consoleModel                }                Connections {                    target: consoleModel                    onChangeCurrentTab: {                        bottomTabView.currentIndex = i + 1                    }                }                BetterTab {                    closable: false                    title: "Log"                    icon: "qrc:/images/log.svg"                    BaseConsole {                        id: logTab                        readOnly: true                        textColor: "#6D6D6E"                        Connections {                            target: appLogger                            onEvent: logTab.append(msg)                            Component.onCompleted: appLogger.getMessages()                        }                    }                }            }        }    }}

Qt界面程序编写的步骤

1. 设计好全局的QAction, 这个可以被顶栏菜单QMenuBar, 工具栏QToolBar 以及 右键弹出菜单QMenu引用.

2. 设计好主窗体布局和主要widget

3. 开始制作各种slot, 并且将QAction connect到对应的slot上, 这一步需要开始设计各个弹出的QDialog

一个未完成的主窗口例子

rockredismain.h

#ifndef ROCKREDISMAIN_H#define ROCKREDISMAIN_H#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
namespace Ui {class RockRedisMain;}class RockRedisMain : public QMainWindow{ Q_OBJECTpublic: explicit RockRedisMain(QWidget *parent = 0); ~RockRedisMain();private slots: void onCustomContextMenuRequested(const QPoint& point); void showContextMenu(QTreeWidgetItem* item, const QPoint& globalPos); void onCurrentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous);private: Ui::RockRedisMain *ui; QSplitter * splitter; QScrollArea *scrollArea; QTreeWidget *treeWidget; QTableWidget* tableWidget; QMenu *fileMenu; QMenu *helpMenu; QToolBar *fileToolBar; QAction *newConnectionAct; QAction *editConnectionAct; QAction *removeConnectionAct; QAction *exitAct; QAction *aboutAct; void initMenu(); QTreeWidgetItem* addTreeNode(QString name, QString description); QTreeWidgetItem* addChildNode(QTreeWidgetItem *parent, QString name, QString description);};#endif // ROCKREDISMAIN_H

rockredismain.cpp

#include "rockredismain.h"#include "ui_rockredismain.h"RockRedisMain::RockRedisMain(QWidget *parent) : QMainWindow(parent), ui(new Ui::RockRedisMain) {    ui->setupUi(this);    initMenu();    splitter = new QSplitter(Qt::Horizontal, this);    setCentralWidget(splitter);    treeWidget = new QTreeWidget();    treeWidget->setHeaderHidden(true);    //treeWidget->setHeaderLabels(QStringList() << "Connections");    treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);    QTreeWidgetItem* item = addTreeNode("Folder", "It's a folder");    addChildNode(item, "A Connection Folder", "first");    addChildNode(item, "B Connection File", "second");    item = addTreeNode("File", "it's a file");    addChildNode(item, "A", "first");    addChildNode(item, "B", "second");    addTreeNode("Folder", "It's a folder");    addTreeNode("File", "it's a file");    addTreeNode("Folder", "It's a folder");    addTreeNode("File", "it's a file");    addTreeNode("Folder", "It's a folder");    addTreeNode("File", "it's a file");    treeWidget->resize(100, 100);    splitter->addWidget(treeWidget);    tableWidget = new QTableWidget();    splitter->addWidget(tableWidget);    splitter->setStretchFactor(1,1);    setWindowTitle(tr("RockRedis"));    resize(800, 600);    connect(treeWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(onCustomContextMenuRequested(QPoint)));    connect(treeWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), SLOT(onCurrentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)));}RockRedisMain::~RockRedisMain() {    delete ui;}void RockRedisMain::initMenu() {    fileMenu = new QMenu(tr("&File"), this);    helpMenu = new QMenu(tr("&Help"), this);    menuBar()->addMenu(fileMenu);    menuBar()->addMenu(helpMenu);    newConnectionAct = new QAction(tr("&New Connection"), this);    newConnectionAct->setShortcut(tr("Ctrl+N"));    newConnectionAct->setStatusTip(tr("Add a new connection"));    //connect(newConnectionAct, SIGNAL(triggered()), this, SLOT(open()));    fileMenu->addAction(newConnectionAct);    editConnectionAct = new QAction(tr("&Edit Connection"), this);    editConnectionAct->setShortcut(tr("Alt+E"));    editConnectionAct->setEnabled(false);    //connect(editConnectionAct, SIGNAL(triggered()), this, SLOT(print()));    fileMenu->addAction(editConnectionAct);    removeConnectionAct = new QAction(tr("Remove Connection"), this);    editConnectionAct->setShortcut(tr("Del"));    removeConnectionAct->setEnabled(false);    //connect(newWindowAct, SIGNAL(triggered(bool)), this, SLOT(newWindow()));    fileMenu->addAction(removeConnectionAct);    exitAct = new QAction(tr("E&xit"), this);    exitAct->setShortcut(tr("Ctrl+Q"));    connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));    fileMenu->addAction(exitAct);    aboutAct = new QAction(tr("&About"), this);    helpMenu->addAction(aboutAct);}QTreeWidgetItem* RockRedisMain::addTreeNode(QString name, QString description) {    QTreeWidgetItem *item = new QTreeWidgetItem(treeWidget, 0);    item->setText(0, name);    item->setText(1, description);    return item;}QTreeWidgetItem* RockRedisMain::addChildNode(QTreeWidgetItem *parent, QString name, QString description) {    QTreeWidgetItem *item = new QTreeWidgetItem(parent, 1);    item->setText(0, name);    item->setText(1, description);    return item;}void RockRedisMain::onCustomContextMenuRequested(const QPoint& point) {    QTreeWidgetItem* item = treeWidget->itemAt(point);    if (item) {        // Note: We must map the point to global from the viewport to        // account for the header.        showContextMenu(item, treeWidget->mapToGlobal(point));    }}void RockRedisMain::showContextMenu(QTreeWidgetItem* item, const QPoint& point) {    QMenu menu;    switch (item->type()) {        case 0:            menu.addAction(editConnectionAct);            menu.addAction(removeConnectionAct);            break;        case 1:            menu.addAction("This is a type 2");            break;    }    menu.exec(point);}void RockRedisMain::onCurrentItemChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) {    if (current == NULL) {        editConnectionAct->setEnabled(false);        removeConnectionAct->setEnabled(false);    } else if (current->type() == 0) {        editConnectionAct->setEnabled(true);        removeConnectionAct->setEnabled(true);    } else {        editConnectionAct->setEnabled(false);        removeConnectionAct->setEnabled(false);    }}

 

转载地址:http://fnmyx.baihongyu.com/

你可能感兴趣的文章
参加婚礼
查看>>
h5 audio相关手册
查看>>
刚毕业从事java开发需要掌握的技术
查看>>
CSS Custom Properties 自定义属性
查看>>
vim
查看>>
MVVM计算器(下)
查看>>
C++中指针和引用的区别
查看>>
簡單分稀 iptables 記錄 udp 微軟 138 端口
查看>>
Java重写equals方法和hashCode方法
查看>>
Spark API编程动手实战-07-join操作深入实战
查看>>
H3C-路由策略
查看>>
centos 修改字符界面分辨率
查看>>
LNMP之Mysql主从复制(四)
查看>>
阅读Spring源代码(1)
查看>>
nagios一键安装脚本,nagios监控被监控主机上的应用服务mysql数据库
查看>>
grep 命令
查看>>
JS二维数组的声明和使用
查看>>
v$archive_gap dg dataguard 断档处理 scn恢复
查看>>
问责IT风险管理:CIO需关注两个重点
查看>>
Winform打包发布图解
查看>>