使用信号和插槽在Qt中与MainWindow通信QDialog(Using Signals and Slots to Comunicate a QDialog with MainWindow in Qt)
好的,我认为是时候得到一些帮助,我一直在练习Qt的信号和插槽,我得到了库存。 我想要的是能够在单击QDialog中的按钮时更改主窗口中的标签。 我一直在寻找,显然唯一的方法是基本上使用信号和插槽,这是我的...
我有一个mainwindow.ui,带有一个名为“pushButton_OpenWindow”的按钮和一个QLabel label_ShowText“,我还有一个包含名为lineEdit_ExternalInput的QLineEdit的externaldialog.ui”和一个名为“pushButton_SendText”的QPushButton,我想要的是更改“label_ShowText” “无论什么价值”lineEdit_ExternalInput“当点击pushButton_SendText”但它不起作用时,当我点击按钮时没有任何错误发生,没有任何警告。
这是不起作用的代码......
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_pushButton_OpenWindow_clicked(); void textValue(const QString &newText); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include "externaldialog.h" #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); ExternalDialog *externalDialog = new ExternalDialog; // connecting signals and slots QObject::connect(externalDialog, SIGNAL(textChanged(QString)), this, SLOT(textValue(QString))); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_OpenWindow_clicked() { ExternalDialog mDialog; mDialog.setModal(true); mDialog.exec(); } void MainWindow::textValue(const QString &newText) { ui->label_ShowText->setText(newText); qDebug()<<"Message from textValue Function \n"; }
externaldialog.h
#ifndef EXTERNALDIALOG_H #define EXTERNALDIALOG_H #include <QDialog> namespace Ui { class ExternalDialog; } class ExternalDialog : public QDialog { Q_OBJECT public: explicit ExternalDialog(QWidget *parent = 0); ~ExternalDialog(); private: Ui::ExternalDialog *ui; signals: void textChanged(const QString&); public slots: void on_pushButton_SendText_clicked(); }; #endif // EXTERNALDIALOG_H
externaldialog.cpp
#include "externaldialog.h" #include "ui_externaldialog.h" #include <QDebug> ExternalDialog::ExternalDialog(QWidget *parent) : QDialog(parent), ui(new Ui::ExternalDialog) { ui->setupUi(this); } ExternalDialog::~ExternalDialog() { delete ui; } void ExternalDialog::on_pushButton_SendText_clicked() { emit textChanged(ui->lineEdit_ExternalInput->text()); qDebug()<<"Sent Message"; }
main.cpp中
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
知道我做错了什么吗? 任何建议将不胜感激。 对不起,我发布了整个代码,但有时最好看到整个图片。
非常感谢
Ok I think is time to get some help, I have been practicing with signals and slots in Qt and I got stocked. What I want is to be able to change a label in mainwindow when a button in a QDialog is clicked. I have been searching and apparently the only way to do this is basically using signals and slots, here is what I have...
I have a mainwindow.ui with a button called "pushButton_OpenWindow" and a QLabel label_ShowText", I also have a externaldialog.ui that contains a QLineEdit called lineEdit_ExternalInput" and a QPushButton called "pushButton_SendText", and what I want is to change "label_ShowText" to whatever value "lineEdit_ExternalInput" is when pushButton_SendText" is clicked but it doesn't work, when I click the button nothing happens no errors, no warnings nothing.
Here is the code that doesn't work...
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void on_pushButton_OpenWindow_clicked(); void textValue(const QString &newText); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include "externaldialog.h" #include <QDebug> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); ExternalDialog *externalDialog = new ExternalDialog; // connecting signals and slots QObject::connect(externalDialog, SIGNAL(textChanged(QString)), this, SLOT(textValue(QString))); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_OpenWindow_clicked() { ExternalDialog mDialog; mDialog.setModal(true); mDialog.exec(); } void MainWindow::textValue(const QString &newText) { ui->label_ShowText->setText(newText); qDebug()<<"Message from textValue Function \n"; }
externaldialog.h
#ifndef EXTERNALDIALOG_H #define EXTERNALDIALOG_H #include <QDialog> namespace Ui { class ExternalDialog; } class ExternalDialog : public QDialog { Q_OBJECT public: explicit ExternalDialog(QWidget *parent = 0); ~ExternalDialog(); private: Ui::ExternalDialog *ui; signals: void textChanged(const QString&); public slots: void on_pushButton_SendText_clicked(); }; #endif // EXTERNALDIALOG_H
externaldialog.cpp
#include "externaldialog.h" #include "ui_externaldialog.h" #include <QDebug> ExternalDialog::ExternalDialog(QWidget *parent) : QDialog(parent), ui(new Ui::ExternalDialog) { ui->setupUi(this); } ExternalDialog::~ExternalDialog() { delete ui; } void ExternalDialog::on_pushButton_SendText_clicked() { emit textChanged(ui->lineEdit_ExternalInput->text()); qDebug()<<"Sent Message"; }
main.cpp
#include "mainwindow.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; w.show(); return a.exec(); }
Any idea what I'm I doing wrong? Any suggestion will be appreciated. Sorry I posted the whole code but sometimes is better to see the whole picture.
Thanks a lot
原文:
最满意答案
好吧,似乎我将成为第一个为自己的问题找到答案的人:)
(1)首先, http://www.muitovar.com/gtk2hs/chap7-2.html上的示例对我不起作用,因为你在gtk2hs中有两个
eventButton
函数,你必须使用Graphics.UI.Gtk.Gdk.Events
的一个Graphics.UI.Gtk.Gdk.Events
。 所以你必须在文件的开头添加:import Graphics.UI.Gtk.Gdk.Events as Ev
然后添加
Ev.
eventButton
,RightButton
和eventSent
前缀。 它现在会工作:)(2)如何响应treeView行的右键单击:
解决了上述问题后,我偶然发现了这个例子,其中显示了如何响应在treeView中选择行。 所以我混合了这两个解决方案,并提出了类似的东西(大多数代码来自treeview示例,我的一些调整):
module Main where {- an example how to select from a list not satisfactory yet: - there should be a simpler way to render a simple list - i could not convert the model i got back to a list from which to get the value - the interface offers a great number of functions and it is very difficult to find which ones are really needed for simple tasks -} import Graphics.UI.Gtk import Graphics.UI.Gtk.ModelView as Model import Graphics.UI.Gtk.Gdk.Events as Ev main :: IO () main = do initGUI -- is start window <- windowNew list <- listStoreNew ["Vince", "Jhen", "Chris", "Sharon"] treeview <- Model.treeViewNewWithModel list Model.treeViewSetHeadersVisible treeview True -- there should be a simpler way to render a list as the following! col <- Model.treeViewColumnNew Model.treeViewColumnSetTitle col "colTitle" renderer <- Model.cellRendererTextNew Model.cellLayoutPackStart col renderer False Model.cellLayoutSetAttributes col renderer list $ \ind -> [Model.cellText := ind] Model.treeViewAppendColumn treeview col --tree <- Model.treeViewGetSelection treeview --Model.treeSelectionSetMode tree SelectionSingle --Model.onSelectionChanged tree (oneSelection list tree) set window [ windowDefaultWidth := 100 , windowDefaultHeight := 200 , containerChild := treeview ] -- here comes the right-click popup eda <- actionNew "EDA" "Edit" Nothing Nothing pra <- actionNew "PRA" "Process" Nothing Nothing rma <- actionNew "RMA" "Remove" Nothing Nothing saa <- actionNew "SAA" "Save" Nothing Nothing agr <- actionGroupNew "AGR1" mapM_ (actionGroupAddAction agr) [eda,pra,rma,saa] uiman <- uiManagerNew uiManagerAddUiFromString uiman uiDecl uiManagerInsertActionGroup uiman agr 0 maybePopup <- uiManagerGetWidget uiman "/ui/popup" let pop = case maybePopup of (Just x) -> x Nothing -> error "Cannot get popup from string" onButtonPress treeview (\x -> if (Ev.eventButton x) == Ev.RightButton then do menuPopup (castToMenu pop) Nothing return (Ev.eventSent x) else return (Ev.eventSent x)) mapM_ (prAct treeview list) [eda,pra,rma,saa] onDestroy window mainQuit widgetShowAll window mainGUI return () uiDecl = "<ui> \ \ <popup>\ \ <menuitem action=\"EDA\" />\ \ <menuitem action=\"PRA\" />\ \ <menuitem action=\"RMA\" />\ \ <separator />\ \ <menuitem action=\"SAA\" />\ \ </popup>\ \ </ui>" -- Handle the right-click. You can write a function that'll respond to various -- actions, like for example: handleAction "EDA" = do something, etc. prAct treeview list a = onActionActivate a $ do name <- actionGetName a -- getting the selected row tree <- Model.treeViewGetSelection treeview -- you can also use treeSelectionGetSelected to get the Iter object -- and then convert it to Int by using listStoreIterToIndex and so get -- the ListStore item at given index sel <- Model.treeSelectionGetSelectedRows tree let s = head (head sel) v <- Model.listStoreGetValue list s putStrLn ("Action Name: " ++ name ++ " | Item: " ++ v)
我希望它对某人有帮助:)
干杯
Okay it seems I'm going be the first one to find answer for my own question :)
(1) First of all the example at http://www.muitovar.com/gtk2hs/chap7-2.html didn't work for me because you have two
eventButton
functions in gtk2hs and you have to use the one fromGraphics.UI.Gtk.Gdk.Events
. So you have to add at the beginning of the file:import Graphics.UI.Gtk.Gdk.Events as Ev
and then add
Ev.
prefix toeventButton
,RightButton
andeventSent
. It'll work now :)(2) How to respond to right clicks on treeView row:
Having solved the aforementioned problem I stumbled upon this example, where it's shown how to respond to selecting a row in treeView. So I mixed those two solutions and came up with something like this (most of the code comes from the treeview example with some of my tweaks):
module Main where {- an example how to select from a list not satisfactory yet: - there should be a simpler way to render a simple list - i could not convert the model i got back to a list from which to get the value - the interface offers a great number of functions and it is very difficult to find which ones are really needed for simple tasks -} import Graphics.UI.Gtk import Graphics.UI.Gtk.ModelView as Model import Graphics.UI.Gtk.Gdk.Events as Ev main :: IO () main = do initGUI -- is start window <- windowNew list <- listStoreNew ["Vince", "Jhen", "Chris", "Sharon"] treeview <- Model.treeViewNewWithModel list Model.treeViewSetHeadersVisible treeview True -- there should be a simpler way to render a list as the following! col <- Model.treeViewColumnNew Model.treeViewColumnSetTitle col "colTitle" renderer <- Model.cellRendererTextNew Model.cellLayoutPackStart col renderer False Model.cellLayoutSetAttributes col renderer list $ \ind -> [Model.cellText := ind] Model.treeViewAppendColumn treeview col --tree <- Model.treeViewGetSelection treeview --Model.treeSelectionSetMode tree SelectionSingle --Model.onSelectionChanged tree (oneSelection list tree) set window [ windowDefaultWidth := 100 , windowDefaultHeight := 200 , containerChild := treeview ] -- here comes the right-click popup eda <- actionNew "EDA" "Edit" Nothing Nothing pra <- actionNew "PRA" "Process" Nothing Nothing rma <- actionNew "RMA" "Remove" Nothing Nothing saa <- actionNew "SAA" "Save" Nothing Nothing agr <- actionGroupNew "AGR1" mapM_ (actionGroupAddAction agr) [eda,pra,rma,saa] uiman <- uiManagerNew uiManagerAddUiFromString uiman uiDecl uiManagerInsertActionGroup uiman agr 0 maybePopup <- uiManagerGetWidget uiman "/ui/popup" let pop = case maybePopup of (Just x) -> x Nothing -> error "Cannot get popup from string" onButtonPress treeview (\x -> if (Ev.eventButton x) == Ev.RightButton then do menuPopup (castToMenu pop) Nothing return (Ev.eventSent x) else return (Ev.eventSent x)) mapM_ (prAct treeview list) [eda,pra,rma,saa] onDestroy window mainQuit widgetShowAll window mainGUI return () uiDecl = "<ui> \ \ <popup>\ \ <menuitem action=\"EDA\" />\ \ <menuitem action=\"PRA\" />\ \ <menuitem action=\"RMA\" />\ \ <separator />\ \ <menuitem action=\"SAA\" />\ \ </popup>\ \ </ui>" -- Handle the right-click. You can write a function that'll respond to various -- actions, like for example: handleAction "EDA" = do something, etc. prAct treeview list a = onActionActivate a $ do name <- actionGetName a -- getting the selected row tree <- Model.treeViewGetSelection treeview -- you can also use treeSelectionGetSelected to get the Iter object -- and then convert it to Int by using listStoreIterToIndex and so get -- the ListStore item at given index sel <- Model.treeSelectionGetSelectedRows tree let s = head (head sel) v <- Model.listStoreGetValue list s putStrLn ("Action Name: " ++ name ++ " | Item: " ++ v)
I hope it'll be helpful for someone :)
Cheers
相关问答
更多-
使用带有Haskell和Gtk2Hs的编号行的SourceView的极简主义代码是: import Graphics.UI.Gtk import Graphics.UI.Gtk.SourceView main :: IO () main= do initGUI window <- windowNew set window [ windowTitle := "SourceView" , windowDefaultWidth := 100 ...
-
gtk2hs安装(gtk2hs installation)[2021-11-12]
您在Gtk2hsSetup.hs中遇到了一个错误,该错误和解决方法在此处介绍。 我建议将自己添加到trac上的该票上,以便在修复程序可用时通知您。 You're hitting a bug in Gtk2hsSetup.hs, the bug and a workaround is described here. I would recommend adding yourself to that ticket on the trac so that you'll be notified when a fix ... -
这个怎么样: window `on` keyPressEvent $ tryEvent $ do 'F':n_ <- eventKeyName let (n, ""):_ = reads n_ liftIO . notebookSetCurrentPage notebook $ n - 1 这是无可救药的部分:有两个部分模式匹配可以抛出异常。 但那没关系,因为这就是tryEvent的用途。 在撰写本文时,所有其他答案都涉及注册许多事件处理程序,而这一个只注册一个。 这应该具有(轻微 ...
-
Gtk2Hs:Widget交互(Gtk2Hs : Widget interaction)[2023-02-01]
我找到了解决问题的方法: 在主程序中,我创建了一个要执行的操作列表的IORef: actionsIO <- newIORef [action_to_do_1,action_to_do_2] 我为文本输入创建了自定义组合小部件 ent <- textEntry window canvas state modele parser info actionsIO 在里面,我执行这样的动作列表: actions <- readIORef actionsIO sequence_ actions 我创建了我的树视图 ... -
gtk2hs:删除窗口小部件后请求重新计算窗口大小(gtk2hs: Request recalculation of windows size after removing a widget)[2023-07-09]
你可以问你的顶级窗口它想要多大,并使它变得那么大: refresh window = do Requisition w h <- widgetSizeRequest window windowResize window w h 要使用它,请将其粘贴在按钮的单击处理程序中: onClicked button (containerRemove box e2 >> refresh window) You can ask your top-level window how big it want ... -
这里有两个来自我的应用的例子。 在main中,我将GTK小部件绑定到变量,并将其绑定到我在其他模块中实现的回调函数。 - 要加载Glade文件: gui <- builderNew builderAddFromFile gui "myGUI.glade" - 关闭申请: - 将窗口“mainWindow”(在Glade文件中定义)绑定到变量 mainWindow <- builderGetObject gui castToWindow "mainWindow" - 将菜单项“menu_Quit”(在Gl ...
-
获取这些参数的原则是模式匹配,如下所示: case rect of Rectangle x y w h -> "The width is " ++ show w ++ " and the height is " ++ show h 这将为case表达式中的w和h指定宽度和高度。 在特定的设置中,这可能会缩短(通过直接在函数的参数上进行模式匹配,通过将rect值分配给模式等),但像这样的模式匹配是主要原则。 The principle behind getting those parameters ou ...
-
用Darcs安装gtk2hs(install gtk2hs with Darcs)[2024-01-08]
在将Haskell绑定安装到它们之前,必须安装gtk C库。 如果需要有关如何执行此操作的说明 ,请访问安装说明并查看操作系统部分。 You must install the gtk C libraries before you install the Haskell bindings to them. Visit the installation instructions and check the section for your operating system if you need instruc ... -
不幸的是,目前没有纯Haskell方法(正确地)实现Widget类型。 您需要在C中实现您的小部件,然后通过FFI导入它。 有很多例子 - 基本上所有gtk + / gtk2hs都是数百个这样做的例子的集合。 Unfortunately, there is currently no pure-Haskell way to (correctly) implement the Widget type class. You'll need to implement your widget in C, then i ...
-
捕获树视图行上的右键单击事件[haskell gtk2hs](capturing right-click event on treeview row [haskell gtk2hs])[2024-04-29]
好吧,似乎我将成为第一个为自己的问题找到答案的人:) (1)首先, http://www.muitovar.com/gtk2hs/chap7-2.html上的示例对我不起作用,因为你在gtk2hs中有两个eventButton函数,你必须使用Graphics.UI.Gtk.Gdk.Events的一个Graphics.UI.Gtk.Gdk.Events 。 所以你必须在文件的开头添加: import Graphics.UI.Gtk.Gdk.Events as Ev 然后添加Ev. eventButton , ...