• 0
cororo

سؤال حول القوائم في qt

سؤال

السلام عليكم ورحمة الله و بركاته

أريد إنشاء قائمة menu لحظة الضغط على زر الفأرة على ال widget ,وأرجوا أن تكون عن طريق محرر qt , فكيف ذلك ؟ :cash:

:ty:

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

13 إجابة على هذا السؤال .

  • 0

وعليكم السلام ورحمة الله وبركاته ،

يوجد طريقتين ، الاولى وهي على مستوى ال widget وذلك باعادة تطبيق الدالة :

contextMenuEvent(QContextMenuEvent *event)

ومن ثم انشاء القائمة وال Actions المطلوبة ، مثال:


void Widget::contextMenuEvent(QContextMenuEvent *event)
{
QMenu menu(this);
// Create your action
menu.addAction(cutAct);
menu.addAction(copyAct);
menu.exec(event->globalPos());
}

اما الطريقة الثانية ، وهي المناسبة معك كما يبدو ، تكون باستدعاء الدالة:

setContextMenuPolicy(Qt::CustomContextMenu);

على ال widget المطلوب .

ومن ثم ربط حدث customContextMenuRequested() مع أي slot تريد ، مثال:


// Create w
w->setContextMenuPolicy(Qt::CustomContextMenu);
connect(w, SIGNAL(customContextMenuRequested(const QPoint&)),this, SLOT(showContextMenu(const QPoint&)));


void Widget::showContextMenu(const QPoint& pos)
{
QMenu menu(this);
// Create your action
menu.addAction(cutAct);
menu.addAction(copyAct);
menu.exec(w->mapToGlobal(pos)());
}

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم

شكرا أخي سودا نيكس, يبدوا لي الأمر مبهما , فمن فضلك هل تعطيني مثالا كاملا على المرفقات إن كان ذلك ممكنا؟؟؟؟؟

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

مثال الطريقة الاولى :

ملف widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class QAction;

class Widget : public QWidget {
Q_OBJECT
public:
Widget(QWidget* parent =0);
private slots:
void doAction1();
void doAction2();
void doAction3();
protected:
void contextMenuEvent(QContextMenuEvent *event);
private:
void createActions();
QAction* action1;
QAction* action2;
};

#endif // WIDGET_H

ملف widget.cpp

#include <QMenu>
#include <QAction>
#include <QContextMenuEvent>
#include <QMessageBox>

#include "widget.h"

Widget::Widget(QWidget* parent):
QWidget(parent)
{
createActions();
}

void Widget::createActions() {
action1 = new QAction("Action1",this);
connect(action1,SIGNAL(triggered()),this,SLOT(doAction1()));

action2 = new QAction("Action2",this);
connect(action2,SIGNAL(triggered()),this,SLOT(doAction2()));
}

void Widget::contextMenuEvent(QContextMenuEvent *event) {
QMenu menu(this);
menu.addAction(action1);
menu.addAction(action2);
menu.addAction("Action3",this,SLOT(doAction3()));

menu.exec(event->globalPos());
}


void Widget::doAction1() {
QMessageBox::information(this,"Action1","Action1 is clicked");
}

void Widget::doAction2() {
QMessageBox::information(this,"Action2","Action2 is clicked");
}

void Widget::doAction3() {
QMessageBox::information(this,"Action3","Action3 is clicked");
}

والمهم هو ان تقوم بانشاء ال actions التي ستكون موجودة على القائمة ، وقد قمت بانشائها بطريقتين : اما مباشرة ك action3 او انشائها في دالة اخرى ك action1,action2

lملف main.cpp


#include <QApplication>
#include "widget.h"

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

Widget w;
w.show();

return app.exec();
}

وجاري كتابة المثال الاخر..

تم تعديل بواسطه SudaNix
1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

المثال الاخر ، ويختلف عن الاول في ان القائمة تظهر عند الضغط على اي widget بداخل ال parent widget ، بمعنى انك لن تحتاج الى اعادة وراثة اي فئة واعادة تنفيذ الدالة contextMenuEvent

ملف widget.h


#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

class QAction;
class QLabel;

class Widget : public QWidget {
Q_OBJECT
public:
Widget(QWidget* parent =0);
private slots:
void showContextMenu(QPoint);
void doAction1();
void doAction2();
void doAction3();

private:
void createActions();
QAction* action1;
QAction* action2;
QLabel* label;
};

#endif // WIDGET_H

ملف widget.cpp

#include <QMenu>
#include <QAction>
#include <QMessageBox>
#include <QLabel>
#include <QHBoxLayout>

#include "widget.h"

Widget::Widget(QWidget* parent):
QWidget(parent)
{
label = new QLabel("right click me to show a menu");
label->setContextMenuPolicy(Qt::CustomContextMenu);

createActions();

connect(label,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(showContextMenu(QPoint)));

QHBoxLayout* layout = new QHBoxLayout(this);
layout->addWidget(label);

}

void Widget::createActions() {
action1 = new QAction("Action1",this);
connect(action1,SIGNAL(triggered()),this,SLOT(doAction1()));

action2 = new QAction("Action2",this);
connect(action2,SIGNAL(triggered()),this,SLOT(doAction2()));
}


void Widget::doAction1() {
QMessageBox::information(this,"Action1","Action1 is clicked");
}

void Widget::doAction2() {
QMessageBox::information(this,"Action2","Action2 is clicked");
}

void Widget::doAction3() {
QMessageBox::information(this,"Action3","Action3 is clicked");
}


void Widget::showContextMenu(QPoint p) {
QMenu menu(this);
menu.addAction(action1);
menu.addAction(action2);
menu.addAction("Action3",this,SLOT(doAction3()));

menu.exec(label->mapToGlobal(p));
}

وملف main كما هو .

النتيجة هنا ظهور قائمة عن الضغط على ال label ، ويمكنك وضع icons و enable/disable على راحتك.

1

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم

آه عذرا أخي سودا لم أكن أقصد هذه الطريقة , فما أقصده على هذا الشكل:

05fig34.gif

هي صورة أخذتها من النت تم تصميم الواجهة ب glut , فبالنقر على المشهد تظهر القائمة عند موقع المؤشر.

أما ما كنت أتحدث عنه هو widget الذي سيحتضن مشهد ال QGLWdget

عمومــا ما أريده هكذا

319837091.png

تم تعديل بواسطه SudaNix
تم حذف الجزء المكرر من الرد
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

سأجرب الطريقة الثانية شكرا لك

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم

شكرا لك جزيلا أخي الكريم arigato gozaimas , لقد إشتغل كما كنت أريد و كما كتبت أنت في المثال الثاني شكرا جزيلا لك.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم

لقد جربت الطريقة الثانية و لكن يبدو أنني لم أفلح في حسن إستعمالها .

لقد فمت بإنشاء widget على سطح form و عملت له promot للفئة التي أنشأتها widget

و حتى الآن لا أعرف المشكلة؟

code widget.cpp


#include "widget.h"
#include <QMenu>
#include <QAction>
#include <QMessageBox>
#include <QLabel>
#include <QHBoxLayout>
#include "widget.h"

Widget::Widget(QWidget *parent) :
QGLWidget(parent)
{
wid = new QWidget;
wid->setContextMenuPolicy(Qt::CustomContextMenu);
createActions();
connect(wid,SIGNAL(customContextMenuRequested(QPoint)),this,SLOT(showContextMenu(QPoint)));
QHBoxLayout* layout = new QHBoxLayout(this);
layout->addWidget(wid);
}
void Widget::initializeGL() {
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_LINE_SMOOTH_HINT);
glEnable(GL_POLYGON_SMOOTH_HINT);
}
void Widget::resizeGL(int w, int h) {
if (w==0)
w=1;
glViewport (0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)w/(GLfloat)h,0.001f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//gluLookAt( Ax, Ay, Az, 0, 0, 0, 0.0, 1.0, 0.0);
}
void Widget::paintGL() {
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
swapBuffers();
}
void Widget::createActions() {
action1 = new QAction("Action1",this);
connect(action1,SIGNAL(triggered()),this,SLOT(doAction1()));

action2 = new QAction("Action2",this);
connect(action2,SIGNAL(triggered()),this,SLOT(doAction2()));
}


void Widget::doAction1() {
QMessageBox::information(this,"Action1","Action1 is clicked");
}

void Widget::doAction2() {
QMessageBox::information(this,"Action2","Action2 is clicked");
}

void Widget::doAction3() {
QMessageBox::information(this,"Action3","Action3 is clicked");
}


void Widget::showContextMenu(QPoint p) {
QMenu menu(this);
menu.addAction(action1);
menu.addAction(action2);
menu.addAction("Action3",this,SLOT(doAction3()));

menu.exec(wid->mapToGlobal(p));
}

code widget.h


#ifndef WIDGET_H
#define WIDGET_H

#include <QGLWidget>
class QAction;

class Widget : public QGLWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);

protected:
void initializeGL();
void resizeGL(int w, int h);
void paintGL();

private slots:
void showContextMenu(QPoint);
void doAction1();
void doAction2();
void doAction3();

private:
void createActions();
QAction* action1;
QAction* action2;
QWidget* wid;
signals:

public slots:

};

#endif // WIDGET_H

code ui_mainwindow.h


/********************************************************************************
** Form generated from reading UI file 'mainwindow.ui'
**
** Created:
** by: Qt User Interface Compiler version 4.6.3
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/

#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H

#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QHeaderView>
#include <QtGui/QMainWindow>
#include <QtGui/QMenuBar>
#include <QtGui/QStatusBar>
#include <QtGui/QToolBar>
#include <QtGui/QWidget>
#include <widget>

QT_BEGIN_NAMESPACE

class Ui_MainWindow
{
public:
QWidget *centralWidget;
widget *widget;
QMenuBar *menuBar;
QToolBar *mainToolBar;
QStatusBar *statusBar;

void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(400, 300);
centralWidget = new QWidget(MainWindow);
centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
widget = new widget(centralWidget);
widget->setObjectName(QString::fromUtf8("widget"));
widget->setGeometry(QRect(60, 30, 271, 181));
MainWindow->setCentralWidget(centralWidget);
menuBar = new QMenuBar(MainWindow);
menuBar->setObjectName(QString::fromUtf8("menuBar"));
menuBar->setGeometry(QRect(0, 0, 400, 25));
MainWindow->setMenuBar(menuBar);
mainToolBar = new QToolBar(MainWindow);
mainToolBar->setObjectName(QString::fromUtf8("mainToolBar"));
MainWindow->addToolBar(Qt::TopToolBarArea, mainToolBar);
statusBar = new QStatusBar(MainWindow);
statusBar->setObjectName(QString::fromUtf8("statusBar"));
MainWindow->setStatusBar(statusBar);

retranslateUi(MainWindow);

QMetaObject::connectSlotsByName(MainWindow);
} // setupUi

void retranslateUi(QMainWindow *MainWindow)
{
MainWindow->setWindowTitle(QApplication::translate("MainWindow", "MainWindow", 0, QApplication::UnicodeUTF8));
} // retranslateUi

};

namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui

QT_END_NAMESPACE

#endif // UI_MAINWINDOW_H

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

استخدم المثال الاول هنا ، واعد تنفيذ الدالة

void contextMenuEvent(QContextMenuEvent *event);

لانه لا حاجة لانشاء widget بداخل اخر ، فنافذة QGLWidget هي QWidget وعند تطبيق الدالة فيها فان حدث الضغط بالزر الايمن سوف يتم ارساله وسوف تعمل الدالة مباشرة.

وبالتالي ملف widget.h سيكون هكذا:

#ifndef WIDGET_H
#define WIDGET_H

#include <QGLWidget>
class QAction;

class Widget : public QGLWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);

protected:
void initializeGL();
void resizeGL(int w, int h);
void paintGL();
void contextMenuEvent(QContextMenuEvent* event);

private slots:
void doAction1();
void doAction2();
void doAction3();

private:
void createActions();
QAction* action1;
QAction* action2;
signals:

public slots:

};

#endif // WIDGET_H

واكمل الباقي..

تم تعديل بواسطه SudaNix
0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم

لم أفلح أيظا سودانيكس هذه المرة, فلقد عملت promot لل wiidget بالكلاس mega3d.

وجعلت في مصمم النوافذ

widget=====SIGNAL(customContextMenuRequested(QPoint))

widget====SLOT(showContextMenu(QPoint)

و لكن مع كل هذا التطبيق لم يعمل .

مع أني لا أعرف بالظبط دور , لأني وضعت this دلالة على الكائن الحاليmega3d.


menu.exec(this->mapToGlobal(p));

mega3d.h


#ifndef MEGA3D_H
#define MEGA3D_H

#include <QGLWidget>
class QAction;
class mega3d : public QGLWidget
{
Q_OBJECT
public:
explicit mega3d(QWidget *parent = 0);
protected:
void initializeGL();
void resizeGL(int w, int h);
void paintGL();

private slots:
void showContextMenu(QPoint p);
void doAction1();
void doAction2();
void doAction3();

private:
void createActions();
QAction* action1;
QAction* action2;
signals:

public slots:

};

#endif // MEGA3D_H

mega3d.cpp


#include "mega3d.h"
#include <QMenu>
#include <QAction>
#include <QMessageBox>
#include <QLabel>
#include <QHBoxLayout>

mega3d::mega3d(QWidget *parent) :
QGLWidget(parent)
{
createActions();
}
void mega3d::initializeGL() {
glShadeModel(GL_SMOOTH);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_LINE_SMOOTH_HINT);
glEnable(GL_POLYGON_SMOOTH_HINT);
}
void mega3d::resizeGL(int w, int h) {
if (w==0)
w=1;
glViewport (0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45.0f,(GLfloat)w/(GLfloat)h,0.001f,100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
//gluLookAt( Ax, Ay, Az, 0, 0, 0, 0.0, 1.0, 0.0);
}
void mega3d::paintGL() {
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
swapBuffers();
}
void mega3d::createActions() {
action1 = new QAction("Action1",this);
connect(action1,SIGNAL(triggered()),this,SLOT(doAction1()));

action2 = new QAction("Action2",this);
connect(action2,SIGNAL(triggered()),this,SLOT(doAction2()));
}


void mega3d::doAction1() {
QMessageBox::information(this,"Action1","Action1 is clicked");
}

void mega3d::doAction2() {
QMessageBox::information(this,"Action2","Action2 is clicked");
}

void mega3d::doAction3() {
QMessageBox::information(this,"Action3","Action3 is clicked");
}


void mega3d::showContextMenu(QPoint p) {
QMenu menu(this);
menu.addAction(action1);
menu.addAction(action2);
menu.addAction("Action3",this,SLOT(doAction3()));

menu.exec(this->mapToGlobal(p));
}

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم

لقد وجدت الحل على النت

و الطريقة سهلة جدا , فقط نضيف :


void mega3d::mouseReleaseEvent ( QMouseEvent * event )
{
if (Qt::RightButton & event->buttons() )
{
QMenu menu;

QAction* openAct = new QAction("Open...", this);

menu.addAction(openAct);

menu.addSeparator();
menu.exec(mapToGlobal(event->pos()));
}
}

إو هي دالة التحرير الفأرة و قد نستعملها في دالة النقر و السحب .


//void mousePressEvent(QMouseEvent *event);
//void mouseMoveEvent(QMouseEvent *event);
//void mouseReleaseEvent(QMouseEvent *event);

و شكرا جزيلا لك و من كل قلبي يا أخي سودانيكس على مساعدتك لي.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

م أفلح أيظا سودانيكس هذه المرة, فلقد عملت promot لل wiidget بالكلاس mega3d.
وجعلت في مصمم النوافذ
widget=====SIGNAL(customContextMenuRequested(QPoint))
widget====SLOT(showContextMenu(QPoint)
و لكن مع كل هذا التطبيق لم يعمل .

طبعا لن يعمل بالشكل الذي قمت به ، لانك قد قمت بالخلط بين طريقتين.

في الطريقة الاولى يجب اعادة تنفيذ الدالة contextMenuEvent فقط.

اما في الثانية فيجب تحديد ال policy على ال widget (المراد انشاء contexMenu عند الضغط عليه بالزر الأيمن ) بأن يستخدم CustomContexMenu ومن ثم ربط الاشارة customContextMenuRequested مع اي دالة slot.

حاليا بما انه قم عمل معك (بنفس فكرة الطريقة الاولى)، جرب استبدال الدالة mouseReleaseEvent بالدالة التالية (وغير ما يلزم) وسيعمل معك .

void contextMenuEvent(QContextMenuEvent *event);

وشكرا.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه
  • 0

السلام عليكم

بالطبع أخي سودانيكس , لقد إشتغلت معي الطريقة الأولى التي قدمتها أنت , شكرا لك.

0

شارك هذا الرد


رابط المشاركة
شارك الرد من خلال المواقع ادناه

  • يستعرض القسم حالياً   0 members

    لا يوجد أعضاء مسجلين يشاهدون هذه الصفحة .