I have the following hierarchy in my Qt Application:
QMainWindow > QWidget (centralWidget) > QWidget (subclassed) > QLabel
Initialization code in my QMainWindow code:
centralWidget = new QWidget();
centralWidget->setGeometry(0,0,width,height);
chatWidget=new ChatWidget(this); // the subclassed QWidget
setCentralWidget(centralWidget);
In my subclassed QWidget initialization (which happens at the same time than the Qt App initialization) I have the following code:
ChatWidget::ChatWidget(QWidget *parent):QWidget(parent)
{
QLabel *lbl;
lbl=new QLabel(this);
lbl->setText("Hello World 1"); <-- Is properly Display
}
void ChatWidget::displayChatAfterButtonPressed()
{
QLabel *lbl;
lbl=new QLabel(this);
lbl->setText("Hello World 2"); <-- Does NOT appear
}
When the QLabel is added from the class initialization then the message is well displayed in the widget.
However when I launch the same code after a button pressed (via a function in the same QWidget subclass), then the text does not appear on screen.
I don't want to use layouts as I need to exactly position my labels.
Tried to repaint, but didn't help neither.
How can I properly and dynamically display a label after the initialization is done ?
Widgets when they are visible for the first time call to be visible to their children, but since you are creating it afterwards they probably are not calling that method, a possible solution is to call the show method.
void ChatWidget::displayChatAfterButtonPressed()
{
QLabel *lbl;
lbl=new QLabel(this);
lbl->setText("Hello World 2");
lbl->show();
}
comment: it seems strange to me that the QMainWindow you set a central widget and then create the chatWidget as a parent to the QMainWindow, it is generally not recommended to add children to the QMainWindow because it has a given structure, what should be done is to place it inside the centralwidget.
We need to show the label created by button click, cause centralwidget was already painted.
Here is a working example, I added this as answer also I noticed better adding chatWidget as child to centralWidget where in your original code its added to the UI .. this is your choice.
Mainwindow:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
//
ui->setupUi(this);
centralWidget = new QWidget();
centralWidget->setGeometry(width,height);
chatWidget=new ChatWidget(centralWidget); // the subclassed QWidget
setCentralWidget(centralWidget);
// added testing
QPushButton *btn = new QPushButton("MyButton",centralWidget);
btn->setGeometry(100,100,100,100);
btn->setMaximumSize(100,100);
connect(btn,&QPushButton::clicked, chatWidget, &ChatWidget::displayChatAfterButtonPressed);
}
and chatWidget:
ChatWidget::ChatWidget(QWidget *parent):QWidget(parent)
{
QLabel *lbl;
lbl=new QLabel(this);
lbl->setText("Hello World 1");
}
void ChatWidget::displayChatAfterButtonPressed()
{
QLabel *lbl;
lbl=new QLabel(this);
lbl->setText("Hello World 2");
lbl->show();
}
Related
I have the following hierarchy in my Qt Application:
QMainWindow > QWidget (centralWidget) > QWidget (subclassed) > QLabel
Initialization code in my QMainWindow code:
centralWidget = new QWidget();
centralWidget->setGeometry(0,0,width,height);
chatWidget=new ChatWidget(this); // the subclassed QWidget
setCentralWidget(centralWidget);
In my subclassed QWidget initialization (which happens at the same time than the Qt App initialization) I have the following code:
ChatWidget::ChatWidget(QWidget *parent):QWidget(parent)
{
QLabel *lbl;
lbl=new QLabel(this);
lbl->setText("Hello World 1"); <-- Is properly Display
}
void ChatWidget::displayChatAfterButtonPressed()
{
QLabel *lbl;
lbl=new QLabel(this);
lbl->setText("Hello World 2"); <-- Does NOT appear
}
When the QLabel is added from the class initialization then the message is well displayed in the widget.
However when I launch the same code after a button pressed (via a function in the same QWidget subclass), then the text does not appear on screen.
I don't want to use layouts as I need to exactly position my labels.
Tried to repaint, but didn't help neither.
How can I properly and dynamically display a label after the initialization is done ?
Widgets when they are visible for the first time call to be visible to their children, but since you are creating it afterwards they probably are not calling that method, a possible solution is to call the show method.
void ChatWidget::displayChatAfterButtonPressed()
{
QLabel *lbl;
lbl=new QLabel(this);
lbl->setText("Hello World 2");
lbl->show();
}
comment: it seems strange to me that the QMainWindow you set a central widget and then create the chatWidget as a parent to the QMainWindow, it is generally not recommended to add children to the QMainWindow because it has a given structure, what should be done is to place it inside the centralwidget.
We need to show the label created by button click, cause centralwidget was already painted.
Here is a working example, I added this as answer also I noticed better adding chatWidget as child to centralWidget where in your original code its added to the UI .. this is your choice.
Mainwindow:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
//
ui->setupUi(this);
centralWidget = new QWidget();
centralWidget->setGeometry(width,height);
chatWidget=new ChatWidget(centralWidget); // the subclassed QWidget
setCentralWidget(centralWidget);
// added testing
QPushButton *btn = new QPushButton("MyButton",centralWidget);
btn->setGeometry(100,100,100,100);
btn->setMaximumSize(100,100);
connect(btn,&QPushButton::clicked, chatWidget, &ChatWidget::displayChatAfterButtonPressed);
}
and chatWidget:
ChatWidget::ChatWidget(QWidget *parent):QWidget(parent)
{
QLabel *lbl;
lbl=new QLabel(this);
lbl->setText("Hello World 1");
}
void ChatWidget::displayChatAfterButtonPressed()
{
QLabel *lbl;
lbl=new QLabel(this);
lbl->setText("Hello World 2");
lbl->show();
}
Good evening, gentleman's.
I am learning to use Scene Builder to create a GUI from scratch, which means i did not create any object at main class; the Scene Builder itself created everything at the FXML file.
So, in this window of mine i have two sliders and a start button, who will require the int values of both sliders to run.
start method would be like
public void start(slider1 int value, slider2 int value){ code }
Sliders in the fxml file, they have a id:
<Slider fx:id="escritoresQuant" blockIncrement="1.0" layoutX="85.0" layoutY="314.0" majorTickUnit="1.0" max="4.0" minorTickCount="0" prefHeight="14.0" prefWidth="71.0" showTickLabels="true" showTickMarks="true" snapToTicks="true" />
<Slider fx:id="leitoresQuant" blockIncrement="1.0" layoutX="85.0" layoutY="349.0" majorTickUnit="1.0" max="6.0" minorTickCount="0" prefHeight="14.0" prefWidth="71.0" showTickLabels="true" showTickMarks="true" snapToTicks="true" />
How can i get int value from both those sliders?
Thanks a lot
Set an eventListener for when the user changes the slider, if you haven't already.
onMouseReleased="#onSliderChanged"
//in the FXML
<Slider fx:id="escritoresQuant" blockIncrement="1.0" majorTickUnit="5.0"
max="26.0" min="-26.0"
minorTickCount="1" onMouseReleased="#onSliderChanged"
prefHeight="38.0" prefWidth="287.0" showTickLabels="true"
showTickMarks="true" snapToTicks="true"
style="-fx-background-color: white;" value="3.0"
BorderPane.alignment="BOTTOM_CENTER" />
//in the Controller class
#FXML
private Slider escritoresQuant;
#FXML
public void onSliderChanged() {
int sliderValue = (int) escritoresQuant.getValue();
System.out.println(sliderValue + " ");
txtOut.setText(escritoresQuant.getValue()+" ");
}
I think that this is what you are looking for.
You should be able to get the value as a double by calling escritoresQuant.getValue()
I am using WizardNewFileCreationPage to create a New File
public void addPages() {
mainPage = new WizardNewFileCreationPage("FILE", getSelection());
mainPage.setTitle("New File");
mainPage.setDescription("Add new file");
addPage(mainPage);
}
I want to add some Radio Buttons to it representing file extensions in this wizard so that users can select one of them as a file extension.
The WizardNewFileCreationPage is not meant to be extended with custom controls. From its JavaDoc:
Subclasses may override
getInitialContents
getNewFileLabel
Subclasses may extend
handleEvent
If you still want to add the radio buttons 'at your own risk', you can try to override createAdvancedControls and append you controls to the parent after calling super.
protected void createAdvancedControls(Composite parent) {
super.createAdvancedControls( parent );
Button radioButton = new Button( parent, SWT.RADIO );
// ...
}
Note that the layout of parent (currently) is a single-columned GridLayout, set the layout data accordingly.
I'm creating rich text component with selection capabilities for JavaFX project and facing some difficulties.
I'm trying to catch on which TextFlow object user presses mouse button and on which another TextFlow he releases it. But after MOUSE_PRESSED event i can interact only with that TextFlow, who fired it, until i release the mouse.
Here is similar example with Labels:
package sample;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception{
AnchorPane root = new AnchorPane();
primaryStage.setTitle("Events Problem Example");
primaryStage.setScene(new Scene(root, 800, 600));
VBox mainVB = new VBox();
root.getChildren().add(mainVB);
//########## Code is here:
for (int i = 0; i < 5; i++) {
final Label label = new Label("label№"+i);
mainVB.getChildren().addAll(label);
label.setOnMouseEntered(mouseEvent -> System.out.println("entering " + label.getText()));
label.setOnMousePressed(mouseEvent -> System.out.println("press mouse button on " + label.getText()));
label.setOnMouseReleased(mouseEvent -> System.out.println("release mouse button on " + label.getText()));
}
//########################
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Try to move mouse over different Labels and watch messages in command line. After that press and hold mouse primary button on any Label and move it again. You'll see that no other Labels will fire any event until you releases the button.
I spend some time searching for the solution but got nothing.
I also tried to manually fire MOUSE_RELEASED for corresponding Label but it didn't help also.
Appreciate your support.
The documentation for MouseEvent details three different modes for handling mouse drag. In the default mode ("simple press-drag-release gesture"), as you've observed, mouse events are delivered only to the node on which the gesture originated.
In "full press-drag-release gesture" mode, MouseDragEvents are delivered to other nodes during the drag. This is the mode you need, and you activate it by calling startFullDrag on the originating node.
(The third mode is "drag-and-drop" gesture, which is for transferring data between nodes and is typically supported by the underlying platform, so you can drag and drop between your JavaFX application and other applications, as well as within the application.)
Try the following code for your event handlers:
label.setOnDragDetected(mouseEvent -> label.startFullDrag());
label.setOnMouseDragEntered(mouseEvent -> System.out.println("entering " + label.getText()));
label.setOnMouseDragReleased(mouseEvent -> System.out.println("release mouse button on " + label.getText()));
I have a project and I need to know how to adding a component in a JFrame when pressing a JButton.
I have added a panel into panel by this code:
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
colorPanel color0=new colorPanel();
color0.setBounds(5,150+nb,300,120);
color0.setLayout(new FlowLayout());
this.getContentPane().add(color0);
this.validate();
System.out.println("add couleur:"+nb);
nb+=50;
}
It works but the problem is that the component is deleted when I maximize or minimize the JFrame.
Thanks.
When you resize your Jframe, a repaint() & paint() methods are called which probably erases your component.